2

I'm using vertx-4.2.6 to build a proxy service which takes requests from clients (for ex: browser, standalone apps etc), invoke a single thirdparty server, gets the response and send the same response back to client who initiated the request.

In this process, I'm using shared Webclient across multiple requests, i'm getting response from thirdparty quickly (mostly in milli seconds) but sometimes the response is not returned back to client and stucks at ctx.end(response).

Whenever i restart my proxy server, it serves requests sometimes without any issues but time goes on, lets say by EOD, for new requests client seeing 503 error -service unavailable I'm using one MainVerticle with 10 instances. I'm not using any worker threads.

Below is the pseudo code:

MainVerticle

DeploymentOptions depOptions = new DeploymentOptions();
                depOptions.setConfig(config);
                depOptions.setInstances(10);
                vertx.deployVerticle(MainVerticle.class.getName(), depOptions);

.....
router.route("/api/v1/*")
                    .handler(new HttpRequestHandler(vertx));

HttpRequestHandler

public class HttpRequestHandler implements Handler<RoutingContext> {

    private final Logger LOGGER = LogManager.getLogger( HttpRequestHandler.class );

    
    private WebClient webClient;
    
    public HttpRequestHandler(Vertx vertx) {
        super(vertx);
        this.webClient=createWebClient(vertx);
    }

    private WebClient createWebClient(Vertx vertx) {
        WebClientOptions options=new WebClientOptions();
        options.setConnectTimeout(30000);
        WebClient webClient = WebClient.create(vertx,options);
        return webClient;
    }

    @Override
    public void handle(RoutingContext ctx) {
    ctx.request().bodyHandler(bh -> {
            
            ctx.request().headers().remove("Host");
            
            StopWatch sw=StopWatch.createStarted();
            LOGGER.info("invoking CL end point with the given request details...");
            /*
             * Invoking actual target
             */
            webClient.request(ctx.request().method(),target_port,target_host, "someURL")
                    .timeout(5000)
                    .sendBuffer(bh)
                    .onSuccess(clResponse -> {
                        LOGGER.info("CL response statuscode: {}, headers: {}",clResponse.statusCode(),clResponse.headers());
                        LOGGER.trace("response body from CL: {}",clResponse.body());
                        sw.stop();
                        LOGGER.info("Timetaken: {}ms",sw.getTime());  //prints in milliseconds
                        
                        
                        
                        LOGGER.info("sending response back to client...."); //stuck here
                        /*
                         * prepare the final response and return to client..
                         */
                        ctx.response().setStatusCode(clResponse.statusCode());
                        ctx.response().headers().addAll(clResponse.headers());
                        
                        if(clResponse.body()!=null) {
                            ctx.response().end(clResponse.body());
                        }else {
                            ctx.response().end();
                        }
                        
                        LOGGER.info("response SENT back to client...!!"); //not getting this log for certain requests and gives 503 - service unavailable to clients after 5 seconds..
                        
                    }).onFailure(err -> {
                        LOGGER.error("Failed while invoking CL server:",err);
                        sw.stop(); 
                        
                        
                        if(err.getCause() instanceof java.net.ConnectException) {
                            connectionRefused(ctx);
                        }else {
                            invalidResponse(ctx);
                        }
                   });
        });

Im suspecting issue might be due to shared webclient. But i'm not sure. I'm new to Vertx and i'm not getting any clue what's going wrong. Please suggest if there are any options to be set on WebClientOptions to avoid this issue.

kaluva
  • 621
  • 8
  • 27
  • The webclient vert.x page has the following In most cases, a Web Client should be created once on application startup and then reused. Otherwise you lose a lot of benefits such as connection pooling and may leak resources if instances are not closed properly. – chhil Oct 14 '22 at 11:24
  • Yes. Im aware.. Thats the reason, i created shared webclient in the constructor and the same will be used for all http requests. – kaluva Oct 15 '22 at 06:53

0 Answers0