简体   繁体   中英

How can I get HttpAsyncClient to act asynchronously?

I am trying to use HttpAsyncClient to stress test my web application by submitting a hundred or thousand HTTP requests a second and timing the response for each one. My code is based on this quickstart guide but it seems that the thread that connects to the server and sends the HTTP request then sits there waiting for the response from the server! Instead I want it to continue sending next HTTP request without waiting for a HTTP response .

Here is my test code:

public class TestAsyncHttpRequest {

    private static final SimpleDateFormat FORMAT = new SimpleDateFormat(
            "yyyy-MM-dd hh:mm:ss.SSS");

    public static void main(String[] args) throws Exception {

        CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
        try {
            // Start the client
            httpclient.start();
            final CountDownLatch latch = new CountDownLatch(100);
            for (int i = 0; i < 100; i++) {
                System.out.println("Sending POST request at "
                        + FORMAT.format(new Date()));
                final HttpPost request = new HttpPost(
                        "http://localhost:8080/test");
                httpclient.execute(request, new FutureCallback<HttpResponse>() {

                    public void completed(final HttpResponse response) {
                        latch.countDown();
                    }

                    public void failed(final Exception ex) {
                        latch.countDown();
                    }

                    public void cancelled() {
                        latch.countDown();
                    }

                });
                Thread.sleep(50);
            }
            latch.await();
        } finally {
            httpclient.close();
        }
    }
}

The corresponding test servlet just print the time of the request and then sleeps for 20 seconds:

public class TestServlet extends HttpServlet {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        getServletContext().log(
                "TestServlet Received POST at: " + fmt.format(new Date()));
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

The servlet output is as follows - notice that it is only receiving two requests every 20 seconds:

INFO: TestServlet Received POST at: 2014-03-28 07:01:16.838
INFO: TestServlet Received POST at: 2014-03-28 07:01:16.838
INFO: TestServlet Received POST at: 2014-03-28 07:01:36.873
INFO: TestServlet Received POST at: 2014-03-28 07:01:36.873
INFO: TestServlet Received POST at: 2014-03-28 07:01:56.881
INFO: TestServlet Received POST at: 2014-03-28 07:01:56.881
INFO: TestServlet Received POST at: 2014-03-28 07:02:16.891
INFO: TestServlet Received POST at: 2014-03-28 07:02:16.891

Is there some configuration option that will allow me to send a thousand HTTP requests to the server without spawning lots of threads?

HttpAsyncClient has limits for total number of concurrent connections and number of concurrent connections per host.

Try to increase them:

CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
    .setMaxConnTotal(100)
    .setMaxConnPerRoute(100)
    .build();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM