1

I'm implementing Java-based HTTP bot for performance testing purposes. Can anyone suggest Java HTTP client library, suitable for multithreaded environment.

It looks like standard answer is Apache HTTP client, but it's synchronous and it seems to me I need some async solution in this case.

3 Answers 3

2

You should use HTTP Client's ThreadSafeClientConnManager. It will allow you to reuse one instance of HttpClient across threads. See this guide for more information.

Sign up to request clarification or add additional context in comments.

Comments

1

Here is a simple example that implements what you want (based on apache httpclient):

public class ApacheHttpTransportImpl extends BaseHttpTransport {
    private final CloseableHttpClient threadSafeClient;
    private final IdleConnectionMonitorThread monitor;  
    public ApacheHttpTransportImpl() throws NoSuchAlgorithmException, KeyManagementException {
        super(config);
        ConnectionSocketFactory socketFactory = new PlainConnectionSocketFactory();
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", socketFactory).build();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(256);
        cm.setDefaultMaxPerRoute(64);
        RequestConfig clientConfig = RequestConfig.custom().setConnectTimeout(2000)
.setSocketTimeout(1000).setConnectionRequestTimeout(2000).build();
        threadSafeClient = HttpClients.custom().setDefaultRequestConfig(clientConfig).setConnectionManager(cm).build();
        monitor = new IdleConnectionMonitorThread(cm, this);
        monitor.setDaemon(true);
        monitor.start();
    }
    public CloseableHttpClient get() {
        return threadSafeClient;
    }

    private static class IdleConnectionMonitorThread extends Thread {
        private final PoolingHttpClientConnectionManager cm;
        private final BlockingQueue<Stop> stopSignal = new ArrayBlockingQueue<Stop>(1);
        private final ApacheHttpTransportImpl cp;
        private static class Stop {
            private final BlockingQueue<Stop> stop = new ArrayBlockingQueue<Stop>(1);
            public void stopped() {
                stop.add(this);
            }
            public void waitForStopped() throws InterruptedException {
                stop.take();
            }
        }
        IdleConnectionMonitorThread(PoolingHttpClientConnectionManager cm, ApacheHttpTransportImpl cp) {
            super();
            this.cm = cm;
            this.cp = cp;
        }
        @Override
        public void run() {
            try {
                Stop stopRequest;
                while ((stopRequest = stopSignal.poll(5, TimeUnit.SECONDS)) == null) {
                    cm.closeExpiredConnections();
                    cm.closeIdleConnections(60, TimeUnit.SECONDS);
                }
                stopRequest.stopped();
            } catch (InterruptedException e) {
            }
        }       
    }
}

And here is how it can be used:

ApacheHttpTransportImpl transport = new ApacheHttpTransportImpl();
HttpGet httpGet = new HttpGet("http://www.google.com");
CloseableHttpResponse httpResponse = transpot.get().execute(httpGet);

Also, you can take a look on Unirest - it is very simple in using, although it is based on apache httpclient as well.

Comments

0

Yeah, that bugs me about the Apache Client. If you only need something simple, you can just use URL and openConnection()

2 Comments

I don't need something simple, I need something that offers good performance and stability :-).
It looks like you can use that HTTPClient in a thread-safe way: hc.apache.org/httpclient-3.x/threading.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.