我正在使用Apache httpasyncclient版本4.0.2开发HTTP客户端应用程序。
我想配置最大待处理请求数。最初我假设这个数字与最大连接数相同。我通过以下方式将其设置为20:
final CloseableHttpAsyncClient httpclient;
在构造函数中:
final NHttpConnectionFactory<ManagedNHttpClientConnection> connFactory = new ManagedNHttpClientConnectionFactory(new DefaultHttpRequestWriterFactory(), new DefaultHttpResponseParserFactory(), HeapByteBufferAllocator.INSTANCE);
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setIoThreadCount(4)
.setConnectTimeout(30000)
.setSoTimeout(30000)
.build();
final PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(ioReactorConfig), connFactory);
final int maxConns = 20;
connManager.setDefaultMaxPerRoute(maxConns);
connManager.setMaxTotal(maxConns);
httpclient = HttpAsyncClientBuilder.create().setConnectionManager(connManager).build();
httpclient.start();
以后:
final BasicAsyncRequestProducer requestProducer = new BasicAsyncRequestProducer(URIUtils.extractHost(URI.create(serverAddress)), request) {
@Override
public void requestCompleted(HttpContext context) {
pendings.add(callback);
logMessage(Direction.REQUEST, req);
handler.onContentWriteCompleted();
}
};
httpclient.execute(requestProducer, HttpAsyncMethods.createConsumer(), new HttpClientContext(), callback);
回调是我处理响应的地方。
作为概念证明,它失败了。确实要运行四个线程,但是当我尝试同时发送20个消息时,只会立即发送8个消息,其余的必须等到服务器响应它们。
Apache调试消息表明确实已创建了20个连接。似乎必须进行更多配置。
答案 0 :(得分:4)
Apache HttpAsyncClient maintains an unbounded request execution queue and does not attempt to limit the number of pending requests. Various applications may or may not want to throttle request rate and there is no easy way to satisfy them all.
One can however fairly easily throttle the number of concurrent requests using a simple semaphore.
final Semaphore semaphore = new Semaphore(maxConcurrencyLevel);
for (int i = 0; i < n; i++) {
semaphore.acquire();
this.httpclient.execute(
new BasicAsyncRequestProducer(target, request),
new MyResponseConsumer(),
new FutureCallback<HttpResponse>() {
@Override
public void completed(final HttpResponse result) {
semaphore.release();
}
@Override
public void failed(final Exception ex) {
semaphore.release();
}
@Override
public void cancelled() {
semaphore.release();
}
});
}