I was using this solution offered by the docs, retrieving directly the webclient from the service record. This was causing memory leaks and heap was maxing out, because I was creating a webclient object every time I would make a request to my proxy.
I knew what i was doing, but i guess calling ServiceDiscovery.realease wasn't enough. I guess there might be two reasons:
1) My bad code (more likely): I was very cautios and checked every possibility, and I'm pretty sure i was releasing the webclient each time. Anyway, it could be that i was missing some ServiceDiscovery.release calls.
2) It is a bad practice to do so, and it should follow a service discovery.close()
private void rerouteToService(RoutingContext routingContext, String root, String uri) {
LOGGER.info("handling request " + routingContext.request().method().name() + " "
+ routingContext.request().absoluteURI());
HttpEndpoint.getWebClient(discovery, record -> record.getLocation().getString("root").equals(root),
webClientAsyncResult -> {
if (webClientAsyncResult.succeeded()) {
WebClient webClient = webClientAsyncResult.result();
Buffer body = routingContext.getBody();
HttpServerRequest httpServerRequest = routingContext.request();
HttpServerResponse httpServerResponse = routingContext.response();
HttpMethod method = httpServerRequest.method();
HttpRequest<Buffer> request = webClient.request(method, uri);
request.timeout(1000);
request.putHeaders(httpServerRequest.headers());
// put, post with body
if (body != null && !body.toString().isEmpty()) {
// send json object does not work...
LOGGER.info("Payload " + body.toString());
request.sendBuffer(body, httpResponseAsyncResult -> handleHttpResponse(uri,
httpServerResponse, httpResponseAsyncResult, webClient, discovery));
} else if (method == HttpMethod.GET) {
handleCachingGetRequest(uri, request, httpServerResponse, routingContext, webClient,
discovery);
} else {
request.send(httpResponseAsyncResult -> handleHttpResponse(uri, httpServerResponse,
httpResponseAsyncResult, webClient, discovery));
}
} else {
BadRequest("service with root " + root + " was not found", routingContext);
}
});
}
now a snippet from my non-memory-leaky code:
In this case I just retrieve the service record, not calliing release and the client is instantiated with keepAlive(false) on start
private void rerouteToService(RoutingContext routingContext, String root, String uri) {
LOGGER.info("handling request " + routingContext.request().method().name() + " "
+ routingContext.request().absoluteURI());
discovery.getRecord(record -> record.getLocation().getString("root").equals(root), recordAsync -> {
if (recordAsync.succeeded() && recordAsync.result()!=null) {
Record serviceRecord = recordAsync.result();
int port = serviceRecord.getLocation().getInteger("port");
String host = serviceRecord.getLocation().getString("host");
Buffer body = routingContext.getBody();
HttpServerRequest httpServerRequest = routingContext.request();
HttpServerResponse httpServerResponse = routingContext.response();
HttpMethod method = httpServerRequest.method();
HttpRequest<Buffer> request = client.request(method, port, host, uri);
request.timeout(1000);
request.putHeaders(httpServerRequest.headers());
if (body != null && !body.toString().isEmpty()) {
request.sendBuffer(body, httpResponseAsyncResult -> {
handleHttpResponse(uri, httpServerResponse, httpResponseAsyncResult, discovery);
// breakerPromise.complete();
});
} else if (method == HttpMethod.GET) {
handleCachingGetRequest(uri, request, httpServerResponse, routingContext, discovery);
} else {
request.send(httpResponseAsyncResult -> {
handleHttpResponse(uri, httpServerResponse, httpResponseAsyncResult, discovery);
// breakerPromise.complete();
});
}
} else {
BadRequest("service with root " + root + " was not found", routingContext);
}
});