我正在使用Spring WebServiceTemplate
Apache HttpClient
(4.5.3)对我的一个客户端执行肥皂请求。我想执行许多异步请求并在得到响应时处理响应。
我的策略是使用单个PoolingHttpClientConnectionManager
并为每个请求执行HttpClientBuilder.setConnectionManager(connectionManager).build()
。
但是在负载下,响应时间开始变慢!我检查了客户仍在快速响应,但是sendSourceAndReceiveToResult
的通话时间过长。为了了解发生了什么,我记录了connectionManager
的统计信息,这就是我得到的:
connectionManager.getTotalStats().getAvailable() --> 40
connectionManager.getTotalStats().getLeased() --> 1 only one connection is used to request!
connectionManager.getMaxTotal() --> 200
connectionManager.getDefaultMaxPerRoute() --> 200
这是我的bean定义
<bean id="myMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="myMessageFactory" />
<property name="messageSender" ref="messageSender"></property>
</bean>
<bean id="messageSender" class="org.springframework.ws.transport.http.HttpComponentsMessageSender"
</bean>
我的连接管理器
public class CustomPoolingHttpClientConnectionManager extends PoolingHttpClientConnectionManager {
private IdleConnectionMonitorThread monitor;
Logger logger = LoggerFactory.getLogger(CustomPoolingHttpClientConnectionManager.class);
private static final class ConnectionManagerInstanceHolder {
private static final CustomPoolingHttpClientConnectionManager instance = new CustomPoolingHttpClientConnectionManager();
}
private static Registry<ConnectionSocketFactory> getSocketFactoryRegistry() {
SSLConnectionSocketFactory socketFactory = null;
try {
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(
new File(System.getProperty("javax.net.ssl.keyStore")),
System.getProperty("javax.net.ssl.keyStorePassword").toCharArray(),
System.getProperty("javax.net.ssl.keyStorePassword").toCharArray()).build();
socketFactory = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
}
catch (Exception ex) {
//
}
return RegistryBuilder.<ConnectionSocketFactory> create()
.register("https", socketFactory)
.build();
}
public static CustomPoolingHttpClientConnectionManager getInstance() {
return ConnectionManagerInstanceHolder.instance;
}
public CustomPoolingHttpClientConnectionManager() {
super ( getSocketFactoryRegistry() );
monitor = new IdleConnectionMonitorThread(this);
monitor.start();
}
// Watches for stale connections and evicts them.
private static class IdleConnectionMonitorThread extends Thread {
Logger logger = LoggerFactory.getLogger(IdleConnectionMonitorThread.class);
// The manager to watch.
private final PoolingHttpClientConnectionManager connectionManager;
// Use a BlockingQueue to stop everything.
private final BlockingQueue<Stop> stopSignal = new ArrayBlockingQueue<Stop>(1);
IdleConnectionMonitorThread(PoolingHttpClientConnectionManager cm) {
super();
this.connectionManager = cm;
}
@Override
public void run() {
try {
// Holds the stop request that stopped the process.
Stop stopRequest;
connectionManager.setMaxTotal(200);
connectionManager.setDefaultMaxPerRoute(200);
// Every 5 seconds.
while ((stopRequest = stopSignal.poll(5, TimeUnit.SECONDS)) == null) {
logger.debug("Available Threads: " + connectionManager.getTotalStats().getAvailable() +
"\nCurrently Working Threads: " + connectionManager.getTotalStats().getLeased() +
"\nTotal Thread count: " + connectionManager.getMaxTotal() +
"\nMax Thread per host: " + connectionManager.getDefaultMaxPerRoute());
// Close expired connections
connectionManager.closeExpiredConnections();
// Optionally, close connections that have been idle too long.
connectionManager.closeIdleConnections(20, TimeUnit.SECONDS);
}
// Acknowledge the stop request.
stopRequest.stopped();
} catch (InterruptedException ex) {
// terminate
}
}
// Pushed up the queue.
private static class Stop {
// The return queue.
private final BlockingQueue<Stop> stop = new ArrayBlockingQueue<Stop>(1);
// Called by the process that is being told to stop.
public void stopped() {
// Push me back up the queue to indicate we are now stopped.
stop.add(this);
}
// Called by the process requesting the stop.
public void waitForStopped() throws InterruptedException {
// Wait until the callee acknowledges that it has stopped.
stop.take();
}
}
}
}
制作HttpClient
private CloseableHttpClient buildHttpClient() {
HttpClientBuilder builder = HttpClientBuilder.create();
RequestConfig.Builder requestConfig = RequestConfig.custom();
requestConfig.setSocketTimeout(2000);
requestConfig.setConnectionRequestTimeout(2000);
requestConfig.setConnectTimeout(2000);
builder.setDefaultRequestConfig(requestConfig.build());
HttpComponentsMessageSender.RemoveSoapHeadersInterceptor interceptor = new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor();
builder.addInterceptorFirst(interceptor);
builder.setConnectionManager( CustomPoolingHttpClientConnectionManager.getInstance() )
.setConnectionManagerShared(true);
return builder.build();
}
设置HttpClient
((HttpComponentsMessageSender) webServiceTemplate.getMessageSenders()[0]).setHttpClient(httpClient);
我确定在收到回复后关闭CloseableHttpClient
。但是我不知道为什么响应速度很慢!我在这里做错了什么?很感谢任何形式的帮助!