我有一个服务,预计将以~5或更多请求/分钟执行请求.此服务依赖于Apache AsyncHttpClient.每隔几分钟,客户端遇到一些导致java.lang.IllegalStateException的条件:请求无法执行; I/O反应器状态:已停止.对客户端的所有请求都以相同的异常消息开始失败.重新启动服务后,将重复此循环.
调试此问题非常困难,因为请求执行失败令人惊讶地不会导致回调AsyncResponse 的failed()方法.
从我可以收集的内容中,在HttpCore NIO中修复了HTTPCORE-370,解决了4.3.2中的类似问题.我使用以下版本 - commons-httpclient-3.1.jar httpasyncclient-4.1.1.jar httpcore-4.4.4.jar httpcore-nio-4.4.4.jar
然而,看到这个问题.任何帮助将非常感激.
我们在同一个tomcat服务器上部署了三个应用程序A,B和C.在A到B之间发生了一个HTTP调用(REST CALL)和从B到C的另一个http调用(REST CALL)
我们最初使用同步HTTP调用,最近我们将代码更改为异步调用.我们使用HttpAsyncClients(应用程序A调用应用程序B)和(应用程序B调用应用程序C).
我们得到间歇性的org.apache.http.ConnectionClosedException:有时我们在应用程序A的日志(Async Client到B)和应用程序B中的某个时间(异步客户端到C)中获得此异常
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setMaxConnPerRoute(100))
.setMaxConnTotal(config.getInt(150)).build();
Run Code Online (Sandbox Code Playgroud)
并且对于我们给予超时的每个请求
final RequestConfig params = RequestConfig.custom().setConnectTimeout(300000) // 5min
.setSocketTimeout(300000).setConnectionRequestTimeout(300000).build();
Run Code Online (Sandbox Code Playgroud)
请在下面找到堆栈跟踪:
org.apache.http.ConnectionClosedException: Connection closed
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.endOfInput(HttpAsyncRequestExecutor.java:344) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:261) [httpcore-nio-4.4.5.jar:na]
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81) [httpasyncclient-4.1.2.jar:na]
at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39) [httpasyncclient-4.1.2.jar:na]
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) [httpcore-nio-4.4.5.jar:4.4.5]
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588) [httpcore-nio-4.4.5.jar:4.4.5]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
Run Code Online (Sandbox Code Playgroud)
请注意这个问题不是重复的 间歇性ConnectionClosedException与httpasynclient stacj跟踪是完全不同的.事件这个问题发生间歇性.
在以前的版本中,HttpClient目标主机已设置为客户端本身。在最新版本(对于HttpAsyncClient4.1.1)中,每次执行请求时,主机都设置为HttpRequest(HttpGet,HttpPost等等。)。
我想使用持久连接,所以我使用HttpAsyncClient。我这样创建和使用它:
CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
List<Future<HttpResponse>> responses = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
HttpGet get = new HttpGet("https://google.com/");
responses.add(client.execute(get, null));
}
for (Future<HttpResponse> response : responses) {
response.get(); //wait for the response
}
Run Code Online (Sandbox Code Playgroud)
如我所测试,它的工作速度比平常更快HttpClient(如果我执行所有请求,然后等待所有响应)。
但是我无法完全了解它是如何工作的。https://google.com/建立了多少个连接?如果我使用client一台主机,然后再使用另一台主机会怎样?(正如我测试的那样,响应可以以任何顺序进行,因此我想至少有2个并行连接)。HttpAsyncClients.createDefault()和之间有什么区别HttpAsyncClients.createPipelining()?
谢谢!
java apache-httpcomponents apache-commons-httpclient apache-httpclient-4.x apache-httpasyncclient
以下是我的代码
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(100)
.setConnectTimeout(100)
.setConnectionRequestTimeout(100).build();
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.build();
httpClient.start();
Run Code Online (Sandbox Code Playgroud)
根据setSocketTimeout值,它应该在100毫秒内超时,但超时需要1000毫秒.但是,setSocketTimeout表示所有大于1000毫秒的值.
我想了解 timeToLive 属性是如何工作的?
这是当您从池中获取连接时,故意关闭连接并返回池的时间间隔吗?
我希望使用持久连接的客户端每隔几秒关闭一次,因此对负载均衡器的请求每隔几秒就会发送到新服务器。
我正在尝试记录来自 http 客户端的原始请求/响应。我正在按照这些日志记录说明中的 log4j2 配置进行操作。
HttpAsync 客户端依赖项:- httpasyncclient(版本 4.1.1)
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingRandomAccessFile name="app-log" fileName="${log.path}/app.log"
filePattern="${log.path}/app-%d{yyyy-MM-dd}.gz">
<PatternLayout>
<pattern>[%-5level] [%X{uuid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<AsyncLogger name="org.apache.http.impl.conn.Wire" level="debug">
<AppenderRef ref="app-log"/>
</AsyncLogger>
<AsyncRoot level="debug" includeLocation="true">
<AppenderRef ref="app-log"/>
</AsyncRoot>
</Loggers>
</Configuration>
Run Code Online (Sandbox Code Playgroud)
它打印正常,但线程上下文没有传递到线路记录器上。
例子 :-
// with uuid, output of logger.debug(ThreadContext.getImmutableContext().toString());
[DEBUG] [c48b97f7-0094-44af-82af-3d6b43d76014] 2016-11-14 17:06:03.408 [http-bio-8080-exec-1] OutboundRequestHandler - {uuid=c48b97f7-0094-44af-82af-3d6b43d76014}
// without uuid
[DEBUG] [] 2016-11-14 17:06:03.440 [I/O dispatcher …Run Code Online (Sandbox Code Playgroud) 我正在尝试选择最好的方法来并行进行大量的http请求。以下是我到目前为止拥有的两种方法:
使用Apache HttpAsyncClient和CompletableFutures:
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setMaxConnPerRoute(2000).setMaxConnTotal(2000)
.setUserAgent("Mozilla/4.0")
.build()) {
httpclient.start();
HttpGet request = new HttpGet("http://bing.com/");
long start = System.currentTimeMillis();
CompletableFuture.allOf(
Stream.generate(()->request).limit(1000).map(req -> {
CompletableFuture<Void> future = new CompletableFuture<>();
httpclient.execute(req, new FutureCallback<HttpResponse>() {
@Override
public void completed(final HttpResponse response) {
System.out.println("Completed with: " + response.getStatusLine().getStatusCode())
future.complete(null);
}
...
});
System.out.println("Started request");
return future;
}).toArray(CompletableFuture[]::new)).get();
Run Code Online (Sandbox Code Playgroud)常规的每请求线程数方法:
long start1 = System.currentTimeMillis();
URL url = new URL("http://bing.com/");
ExecutorService executor = Executors.newCachedThreadPool();
Stream.generate(()->url).limit(1000).forEach(requestUrl ->{
executor.submit(()->{
try {
URLConnection conn = requestUrl.openConnection();
System.out.println("Completed …Run Code Online (Sandbox Code Playgroud)我正在使用带有身份验证的代理运行一些异步 GET 请求。执行 HTTPS 请求时,我总是在 2 个成功的异步请求后遇到异常:java.lang.IllegalArgumentException: Auth scheme may not be null
在没有代理的情况下执行 GET 请求或使用 http 而不是 https 时,从未发生异常。
来自Apache HttpAsyncClient 示例的示例
HttpHost proxy = new HttpHost("proxyname", 3128);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("proxyuser", "proxypass"));
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom().setDefaultCredentialsProvider(credsProvider).build();
httpClient.start();
RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
for (int i = 0; i < 3; i++) {
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(config);
httpClient.execute(httpGet, new FutureCallback<HttpResponse>() {
public void failed(Exception ex) {
ex.printStackTrace(); // Exception occures here afther …Run Code Online (Sandbox Code Playgroud) 我正在使用httpcore-nio-4.4.5.jar。我正在使用elasticsearch RestHighLevelClient 与我们的elasticsearch 服务器交互。这一切都工作正常,除了有时我们会突然出现 I/O 反应器停止错误。
ES 方面一切似乎都很好。没有奇怪的行为。
这就是我初始化 ES 客户端的方式。
public synchronized RestHighLevelClient getHighLevelClient() throws ManagerException {
if (highLevelClient != null) {
return highLevelClient;
}
Map<String, Integer> map = getEsServers(esAddresses);
HttpHost[] hosts = new HttpHost[map.size()];
int i = 0;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
hosts[i++] = new HttpHost(entry.getKey(), entry.getValue(), "http");
LOGGER.info(entry.getKey() + " " + entry.getValue());
}
RestClientBuilder restClientBuilder = RestClient.builder(hosts);
highLevelClient = customizeHttpClient(restClientBuilder);
return highLevelClient;
}
Run Code Online (Sandbox Code Playgroud)
public RestHighLevelClient customizeHttpClient(RestClientBuilder restClientBuilder) {
Header[] defaultHeaders = new Header[2]; …Run Code Online (Sandbox Code Playgroud) 通过典型HttpAsyncClients示例:
public class AsyncClientHttpExchange {
public static void main(final String[] args) throws Exception {
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
httpclient.start();
HttpGet request = new HttpGet("http://httpbin.org/get");
Future<HttpResponse> future = httpclient.execute(request, null);
HttpResponse response = future.get();
System.out.println("Response: " + response.getStatusLine());
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有响应,设置重试次数的方法是什么?我可以看到5.
随着httpClientBuilder存在setRetryHandler:
httpClientBuilder.setRetryHandler(new MyRequestRetryHandler(_maxRetryCount));
Run Code Online (Sandbox Code Playgroud)
有什么办法HttpAsyncClients?
apache httpclient apache-httpclient-4.x apache-httpasyncclient