PoolingHttpClientConnectionManager不执行并行请求

时间:2019-02-14 11:49:22

标签: java spring multithreading apache webservicetemplate

我正在使用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。但是我不知道为什么响应速度很慢!我在这里做错了什么?很感谢任何形式的帮助!

0 个答案:

没有答案