我们正在对使用 vertx 4.1.2 的代码进行性能测试。我们有一个 http 客户端对另一个服务进行 REST 发布。虽然我们的负载(每秒 50 个事务)似乎并没有使服务超载以缓慢响应,但确实会出现如下故障
12:15:21.810 [vert.x-eventloop-thread-1] (gateway-ist-tcp-server-56-5n8ft-121977) WARN ourClient - The timeout period of 250ms has been exceeded while executing POST /xxxx for server xxx-xxx.internal:443
12:16:22.006 [vert.x-eventloop-thread-1] ERROR io.vertx.core.http.impl.HttpClientRequestImpl - io.vertx.core.http.impl.NoStackTraceTimeoutException: The timeout period of 250ms has been exceeded while executing POST /xxxx for server xxx-xxx.internal:443
12:16:22.006 [vert.x-eventloop-thread-1] ERROR io.vertx.core.http.impl.HttpClientRequestImpl - io.vertx.core.VertxException: Connection was closed
12:16:22.007 [vert.x-eventloop-thread-1] () WARN io.netty.util.concurrent.AbstractEventExecutor - A task raised an exception. Task: io.vertx.core.http.impl.Http1xClientConnection$StreamImpl$$Lambda$3478/0x000000084132f040@26e9f1f6
java.lang.IllegalStateException: Attempt to recycle more than permitted
at io.vertx.core.net.impl.pool.SimpleConnectionPool.recycle(SimpleConnectionPool.java:652) ~[vertx-core-4.1.2.jar!/:4.1.2]
at io.vertx.core.net.impl.pool.SimpleConnectionPool.access$2500(SimpleConnectionPool.java:79) ~[vertx-core-4.1.2.jar!/:4.1.2]
at io.vertx.core.net.impl.pool.SimpleConnectionPool$LeaseImpl.recycle(SimpleConnectionPool.java:620) ~[vertx-core-4.1.2.jar!/:4.1.2]
at io.vertx.core.http.impl.HttpClientImpl.lambda$null$5(HttpClientImpl.java:618) ~[vertx-core-4.1.2.jar!/:4.1.2]
at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.handleClosed(Http1xClientConnection.java:603) ~[vertx-core-4.1.2.jar!/:4.1.2]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) [netty-common-4.1.66.Final.jar!/:4.1.66.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) [netty-common-4.1.66.Final.jar!/:4.1.66.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) [netty-transport-4.1.66.Final.jar!/:4.1.66.Final]
这似乎是一些内部 vertx 错误?
作为参考,我们使用 WebClientOptions setKeepAlive(true)
和setKeepAliveTimeout(60)
实际调用是
webClient
.post(443, "xxx-xxx.internal", "/xxxx")
.timeout(250)
.as(BodyCodec.string())
.putHeader("Content-Type", "application/json; charset=ISO-8859-1")
.putHeader("Accept", "application/json")
.sendJsonObject(jsonReq, ar ->
{
if (ar.succeeded()) {
final HttpResponse<String> response = ar.result();
resultPromise.complete(response.body());
} else {
log.warn(ar.cause().getMessage());
resultPromise.fail(new RuntimeException("Rest call failed"));
}
});
我觉得第二个错误发生在第一个错误之后几乎一分钟有点可疑 - 而我们的 keepAliveTimeout 是 60 秒?
我们可能在连接池中的连接用完了,但我认为这不会导致这类错误吗?
欢迎大家提出意见。