Java 使用Http客户端的SpringREST模板在性能测试期间显示高响应时间
我已经创建了一个Spring引导包装器应用程序,它在REST模板的帮助下调用RESTAPI。起初,我只使用Rest模板bean,在性能测试期间,主应用程序和包装器之间的增量响应时间仅为5-10ms左右 为了更好地控制并发和HTTP连接,我们决定使用Java 使用Http客户端的SpringREST模板在性能测试期间显示高响应时间,java,spring-boot,performance-testing,resttemplate,apache-httpclient-4.x,Java,Spring Boot,Performance Testing,Resttemplate,Apache Httpclient 4.x,我已经创建了一个Spring引导包装器应用程序,它在REST模板的帮助下调用RESTAPI。起初,我只使用Rest模板bean,在性能测试期间,主应用程序和包装器之间的增量响应时间仅为5-10ms左右 为了更好地控制并发和HTTP连接,我们决定使用httpclient-4.5.10 jar,并使用CloseableHttpClient创建Rest模板Bean。然而,在实现此功能后,我们注意到平均增量响应时间激增到82 ms以上。经过仔细分析,我们发现commonhttp[app name]:ex
httpclient-4.5.10 jar
,并使用CloseableHttpClient
创建Rest模板Bean。然而,在实现此功能后,我们注意到平均增量响应时间激增到82 ms以上。经过仔细分析,我们发现commonhttp[app name]:execute
大约需要81.4 ms。这意味着HTTP客户端需要更高的响应时间。我们尝试了几种方法来调整性能,方法是更改保持活动的策略、线程数等,但似乎没有一种有效
以下是Http客户端配置:
// Determines the timeout in milliseconds until a connection is established.
@Value("${http-client.connect-timeout}")
private int connectTimeout;
// The timeout when requesting a connection from the connection manager.
@Value("${http-client.request-timeout}")
private int requestTimeout;
// The timeout for waiting for data
@Value("${http-client.socket-timeout}")
private int socketTimeout;
@Value("${http-client.max-total-connections}")
private int maxTotalConnections;
@Value("${http-client.default-max-per-route}")
private int defaultMaxPerRoute;
@Value("${http-client.default-keep-alive-time}")
private int defaultKeepAliveTime;
@Value("${http-client.close-idle-connection-wait-time}")
private int closeIdleConnectionWaitTime;
@Bean
public PoolingHttpClientConnectionManager poolingConnectionManager() {
SSLContextBuilder builder = new SSLContextBuilder();
try {
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
} catch (NoSuchAlgorithmException | KeyStoreException e) {
log.error("Pooling Connection Manager Initialisation failure because of {}", e.getMessage());
}
SSLConnectionSocketFactory sslsf = null;
try {
sslsf = new SSLConnectionSocketFactory(builder.build());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
log.error("Pooling Connection Manager Initialisation failure because of {}", e.getMessage());
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory>create().register("https", sslsf)
.register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
poolingConnectionManager.setMaxTotal(maxTotalConnections);
poolingConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
return poolingConnectionManager;
}
@Bean
public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
return new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
HeaderElementIterator it = new BasicHeaderElementIterator
(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
return Long.parseLong(value) * 1000;
}
}
return defaultKeepAliveTime;
}
};
}
@Bean
public CloseableHttpClient httpClient() {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(requestTimeout)
.setConnectTimeout(connectTimeout)
.setSocketTimeout(socketTimeout).build();
return HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(poolingConnectionManager())
.setKeepAliveStrategy(connectionKeepAliveStrategy())
.build();
}
@Bean
public Runnable idleConnectionMonitor(final PoolingHttpClientConnectionManager connectionManager) {
return new Runnable() {
@Override
@Scheduled(fixedDelay = 10000)
public void run() {
try {
if (connectionManager != null) {
log.trace("run IdleConnectionMonitor - Closing expired and idle connections...");
connectionManager.closeExpiredConnections();
connectionManager.closeIdleConnections(closeIdleConnectionWaitTime, TimeUnit.MILLISECONDS);
} else {
log.trace("run IdleConnectionMonitor - Http Client Connection manager is not initialised");
}
} catch (Exception e) {
log.error("run IdleConnectionMonitor - Exception occurred. msg={}, e={}", e.getMessage(), e);
}
}
};
}
应用程序属性:
# HTTP Client configs
http-client.connect-timeout: 2000
http-client.request-timeout: 5000
http-client.socket-timeout: 5000
http-client.max-total-connections: 200
http-client.default-max-per-route: 50
http-client.default-keep-alive-time: 300000
http-client.close-idle-connection-wait-time: 480000
# HTTP Client configs
http-client.connect-timeout: 2000
http-client.request-timeout: 5000
http-client.socket-timeout: 5000
http-client.max-total-connections: 200
http-client.default-max-per-route: 50
http-client.default-keep-alive-time: 300000
http-client.close-idle-connection-wait-time: 480000