Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PoolgClientConnectionManager经常出现SSLPeerUnverifiedException_Java_Ssl_Apache Httpclient 4.x - Fatal编程技术网

Java PoolgClientConnectionManager经常出现SSLPeerUnverifiedException

Java PoolgClientConnectionManager经常出现SSLPeerUnverifiedException,java,ssl,apache-httpclient-4.x,Java,Ssl,Apache Httpclient 4.x,在一个系统上,我们正在使用PoolgClientConnectionManager 4.2.1(由于其他依赖关系,我们目前无法更新它) 当有超过一定数量的请求时,我们开始为单个请求获取SSLPeerUnverifiedExceptions,我目前无法找出原因,也因为一些Javadoc只显示“不推荐” 以下是池的设置: SchemeRegistry schemeRegistry = SchemeRegistryFactory.createDefault(); Scheme https = getH

在一个系统上,我们正在使用PoolgClientConnectionManager 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);
以下是日志:

尝试工作:

PoolgClientConnectionManager“连接请求:[路由:{s}->保持活动状态:20;分配的路由:20个,共20个;分配的总数:20个,共20个]”
DefaultClientConnection“连接0.0.0.0:49954[服务器ip]:443已关闭”
PoolgClientConnectionManager“已租用的连接:[id:94198][路由:{s}->保持活动状态:19;分配的路由:20个,共20个;分配的总数:20个,共20个]”
DefaultClientConnectionOperator“连接到myserver:443”

失败的尝试:

PoolgClientConnectionManager“连接请求:[路由:{s}->][保持活动状态的总数:19;分配的路由:20个,共20个;分配的总数:20个,共20个]”
DefaultClientConnection“连接0.0.0.0:49953[服务器ip]:443已关闭”
PoologClientConnectionManager“已租用的连接:[id:94196][route:{s}->][保持活动状态的总数:18;分配的路由:20个,共20个;分配的总数:20个,共20个]”
DefaultClientConnectionOperator“连接到myserver:443”
DefaultClientConnection“连接org.apache.http.impl.conn。DefaultClientConnection@4821fdeb关闭”
DefaultClientConnection“连接org.apache.http.impl.conn。DefaultClientConnection@4821fdeb“关闭”
PoolgClientConnectionManager“连接[id:94196][路由:{s}->]可以保持活动状态9223372036854775807毫秒”
DefaultClientConnection“连接org.apache.http.impl.conn。DefaultClientConnection@4821fdeb关闭”
PoologClientConnectionManager“已释放连接:[id:94196][route:{s}->][保持活动状态的总数:18;分配的路由:20个中的19个;分配的总数:20个中的19个]”

除此之外,我想知道如何消除异常

  • 如果池太小,因为所有路由都是永久分配的
  • 如果我作为构造函数arg传递的生存时间(5000毫秒)得到尊重,当它说“可以保持生存9223372036854775807毫秒”
  • 在失败的尝试中关闭连接的原因
通过在异常情况下添加重试,提前关闭过期和空闲的连接,解决了该问题

...
    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);
            }
        }
    }
}

问题是后端节点的证书导致重新协商失败。作为一种变通方法,jvm参数已通过-Djdk.tls.allowUnsafeServerCertChange=true和-Dsun.security.ssl.allowUnsafeRenegotiation=true进行了丰富