我正在加载测试外部第三方API,初始qps为每秒2个请求。当我使用JMeter并运行测试50秒,将请求直接发送到API时,我得到的平均响应时间为4秒,故障率为0%,在所有100个请求中(此API需要一些严重的性能调整) ,所以我现在不会增加负荷。)
在其他测试场景中,我在此API前面设置了一个Spring Boot Rest应用程序,以使用Apache Http客户端修复对API的请求。但是,当我使用相同的负载运行测试时,将它们指向此应用程序,我开始获得套接字读取超时(它们配置为60秒)。在另一个实现中,不使用Apache Http Client,手动修复请求,打开和关闭Java HttpsURLConnection,我没有读取超时,结果与第一个场景中直接发送请求一致。使用http客户端,超时开始在测试过程中发生,而不是在第一次请求中,我得到10%的失败率。我联系了API开发人员,看起来他们身边没有API错误,但我还是无法用它们仔细调试。我假设现在是Http客户端的一些配置错误。
我将Http Client配置为每个路由30个工作者,最多100个连接,以及所有超时(connect,connectionRequest,socket),到60s。
任何可能出错的想法?
修改
这就是我创建客户端的方式:
@Bean
public CloseableHttpClient httpClient() {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(30);
SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(60000).build();
cm.setDefaultSocketConfig(socketConfig);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(60000)
.setConnectionRequestTimeout(60000)
.setSocketTimeout(60000).build();
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm).setDefaultRequestConfig(requestConfig)
.build();
return httpclient;
}
然后,在服务中,我只是打电话:
StringWriter writer = new StringWriter();
objectMapper.writeValue(writer, payloadObj);
HttpPost httpRequest = new HttpPost(endpointString);
httpRequest.addHeader("Content-Type", "application/json");
httpRequest.setEntity(new StringEntity(writer.toString(), "UTF-8"));
try (CloseableHttpResponse httpResponse = httpClient.execute(httpRequest)) {
String rawResponse = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
// Do something with response
}
修改
我得到的例外是:
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)