1 year ago
#215775
zhuangjingwen
"IllegalStateException: Unexpected request state READY" when using HttpAsyncClient under high concurrency
We have a HttpAsyncUtil to process HTTP POST requests.
public class HttpAsyncUtil {
private static CloseableHttpAsyncClient client = null;
static {
try {
// Connect time out: 2s, read time out: 10s, request time out: 5s
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(2000).setSocketTimeout(10000).setConnectionRequestTimeout(5000).build();
IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setIoThreadCount(20).setSoKeepAlive(false).build();
ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// don't check
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// don't check
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, null);
SSLIOSessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext, SSLIOSessionStrategy.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<SchemeIOSessionStrategy> registry = RegistryBuilder.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", sslioSessionStrategy)
.build();
PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor,registry);
connectionManager.setMaxTotal(2000);
connectionManager.setDefaultMaxPerRoute(2000);
client = HttpAsyncClients.custom().setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
} catch (Exception ex) {
// System.exit(0);
}
}
public static void post(String url, Map<String, String> params, Map<String, String> headers, FutureCallback<HttpResponse> callback) throws Exception {
HttpPost httpPost = new HttpPost(url);
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
if (params != null) {
List<NameValuePair> parameters = new ArrayList<>(params.size());
for (Map.Entry<String, String> entry : params.entrySet()) {
parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
httpPost.setEntity(formEntity);
}
client.start();
client.execute(httpPost,callback);
}
It works well under low concurrency. However, something went wrong when processing pressure test.
java.lang.IllegalStateException: Unexpected request state READY
at org.apache.http.util.Asserts.check(Asserts.java:46)
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.outputReady(HttpAsyncRequestExecutor.java:231)
at org.apache.http.impl.nio.DefaultNHttpClientConnection.produceOutput(DefaultNHttpClientConnection.java:290)
at org.apache.http.impl.nio.client.InternalIODispatch.onOutputReady(InternalIODispatch.java:86)
at org.apache.http.impl.nio.client.InternalIODispatch.onOutputReady(InternalIODispatch.java:39)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(AbstractIODispatch.java:145)
at org.apache.http.impl.nio.reactor.BaseIOReactor.writable(BaseIOReactor.java:188)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:341)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:588)
at java.base/java.lang.Thread.run(Thread.java:834)
The source code shows that the Connection state
is expected to be BODY_STREAM
or ACK_EXPECTED
but its actually READY
. It seems that something special events reset the Connection state
. But we cannot find more evidence on this.
java
apache-httpasyncclient
0 Answers
Your Answer