与PoolingClientConnectionManager相当频繁的SSLPeerUnverifedException

时间:2015-12-09 15:18:06

标签: java ssl apache-httpclient-4.x

在我们使用PoolingClientConnectionManager 4.2.1的系统上(由于其他依赖性,我们目前无法更新它。)

当有超过一定数量的请求时,我们开始为单个请求获取SSLPeerUnverifiedExceptions,我目前无法弄清楚原因,也因为某些Javadoc只显示“已弃用”。

以下是汇集的设置:

SchemeRegistry schemeRegistry = SchemeRegistryFactory.createDefault();
Scheme https = getHttpsScheme(sslContext, port);
schemeRegistry.register(https);

PoolingClientConnectionManager connectionManager =
            new PoolingClientConnectionManager(schemeRegistry, 5000, TimeUnit.MILLISECONDS);
connectionManager.setMaxTotal(20);
connectionManager.setDefaultMaxPerRoute(20);

return new DefaultHttpClient(connectionManager);

以下是日志:

尝试工作: PoolingClientConnectionManager "Connection request: [route: {s}->https://myserver][total kept alive: 20; route allocated: 20 of 20; total allocated: 20 of 20]" DefaultClientConnection "Connection 0.0.0.0:49954<->[server_ip]:443 closed" PoolingClientConnectionManager "Connection leased: [id: 94198][route: {s}->https://myserver][total kept alive: 19; route allocated: 20 of 20; total allocated: 20 of 20]" DefaultClientConnectionOperator "Connecting to myserver:443"

尝试失败: PoolingClientConnectionManager "Connection request: [route: {s}->https://myserver ][total kept alive: 19; route allocated: 20 of 20; total allocated: 20 of 20]" DefaultClientConnection "Connection 0.0.0.0:49953<->[server_ip]:443 closed" PoolingClientConnectionManager "Connection leased: [id: 94196][route: {s}->https://myserver ][total kept alive: 18; route allocated: 20 of 20; total allocated: 20 of 20]" DefaultClientConnectionOperator "Connecting to myserver:443" DefaultClientConnection "Connection org.apache.http.impl.conn.DefaultClientConnection@4821fdeb closed" DefaultClientConnection "Connection org.apache.http.impl.conn.DefaultClientConnection@4821fdeb shut down" PoolingClientConnectionManager "Connection [id: 94196][route: {s}->https://myserver ] can be kept alive for 9223372036854775807 MILLISECONDS" DefaultClientConnection "Connection org.apache.http.impl.conn.DefaultClientConnection@4821fdeb closed" PoolingClientConnectionManager "Connection released: [id: 94196][route: {s}->https://myserver ][total kept alive: 18; route allocated: 19 of 20; total allocated: 19 of 20]"

除了如何摆脱异常之​​外,我想知道

  • 如果池很小,因为所有路由都是永久分配的
  • 如果我作为构造函数arg(5000毫秒)传递的生存时间被尊重,当它说“可以为9223372036854775807 MILLISECONDS保持活着”
  • 为什么连接在失败的尝试中被关闭。

1 个答案:

答案 0 :(得分:0)

通过在事先关闭过期和空闲连接的情况下添加重试来解决问题。

...
    try {
        result = performWsRequest(request, soapAction);
    } catch (WebServiceIOException | SSLPeerUnverifiedException ex) {
        if (retryAttempt) {
            logAndThrowExceptionUponWsRequest(ex);
        } else {
            LOGGER.info("Re-trying webservice-request");
            cleanConnections();
            result = performWsRequestWithRetry(request, soapAction, true);
        }
    } catch (Exception e) {
        logAndThrowExceptionUponWsRequest(e);
    }
...

private synchronized void cleanConnections() {

    LOGGER.info(
            "Cleaning connections. Total message-senders: {}",
            this.webServiceTemplate.getMessageSenders().length);

    for (WebServiceMessageSender messageSender : this.webServiceTemplate.getMessageSenders()) {

        if (messageSender instanceof HttpComponentsMessageSender) {

            LOGGER.info("Checking connections of message-sender {}", messageSender);
            HttpComponentsMessageSender httpComponentsMessageSender = (HttpComponentsMessageSender)messageSender;

            if (httpComponentsMessageSender.getHttpClient() != null
                && httpComponentsMessageSender.getHttpClient().getConnectionManager() != null) {
                LOGGER.info("Closing connections");
                httpComponentsMessageSender.getHttpClient().getConnectionManager().closeExpiredConnections();
                httpComponentsMessageSender.getHttpClient()
                        .getConnectionManager()
                        .closeIdleConnections(5000, TimeUnit.MILLISECONDS);
            }
        }
    }
}