java - SSLHandshakeException 可以是可重试的异常吗?

标签 java ssl exception jersey retry-logic

我有一个服务到服务的连接,它间歇性地从 Jersey 客户端抛出 SSLHandshakeExceptions。

public static class MyClientFilter extends ClientFilter{
    @Override
    public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
        try {
            return getNext().handle(cr);
        } catch (ClientHandlerException e) {
            Throwable rootCause = e.getCause() != null ? e.getCause() : e;
            if (ConnectException.class.isInstance(rootCause) ||
                        SocketException.class.isInstance(rootCause) ||
                        SSLHandshakeException.class.isInstance(rootCause) //maybe?
                ) {
                //do some retry logic
            }
        }
    }
}

它只是间歇性地(很少)发生的事实告诉我,我的证书和 TLS 都配置正确。在我的客户端中,如果由于连接或套接字异常而失败,我将尝试重试连接。我正在考虑使 SSLHandshakeException 也成为可重试的异常,因为在我的情况下它似乎应该是,但我想知道 SSLHandshakeException 是否可能是由连接或套接字问题引起的,如果是这样,有没有办法告诉?

更新:

异常消息似乎表明它可能是与 SSL 配置无关的连接问题:

Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:249)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:149)
... 44 common frames omitted

最佳答案

Can a SSLHandshakeException be a retry-able exception?

你问的不是很清楚:

  • SSLHandshakeException 本身会重试吗? 不。当然不是。
  • 是否允许在 SSLHandshakeException 之后重试连接? 是的,您可以重试。
  • 是否建议重试? 它可能会再次失败,但这取决于导致连接失败的原因。
  • 建议反复重试吗? 绝对不是。

实际上,这可以归结为诊断连接失败的原因。为此,您需要为 SSL 连接启用客户端调试日志记录。

此类问题的一个常见原因是客户端和服务器无法协商出一个双方都能接受的 SSL/TLS 协议(protocol)版本或加密套件。当一端使用(按照当前标准)不安全的旧 SSL/TLS 堆栈时,通常会发生这种情况。如果这是根本原因,那么重试将无济于事。

也有可能……但极不可能……服务器或网络在错误的时间出现“故障”。


The message of the exception seems to indicate that it could be a connection issue that is not related to SSL configuration.

其实我是怀疑的。如果协商失败,服务器简单地关闭连接是标准行为;见RFC 8446 Section 4.1了解详情。客户端会将其视为断开的连接。

关于java - SSLHandshakeException 可以是可重试的异常吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51788437/

相关文章:

c# - 即使有 while 循环,Try/catch 函数也仅运行一次 C#

Java:检查一个数组中的重复值并将更简单的 ID 分配给另一个相同大小的数组

java - Jackson 在序列化期间排除了容器(List、Map、Collection)的类型信息

ssl - Hashicorp Consul - 如何从 Kubernetes 集群中的 Pod 中执行经过验证的 TLS

php - SSL 页面发布到非安全表单

c++ - 当函数中静态变量的构造函数异常终止时会发生什么?

java - 将文本文件转换为 csv 格式 Java

java - 从正则表达式匹配器检索捕获组

java - JDK8 -> JDK10 : PKIX path building failed: SunCertPathBuilderException: unable to find valid certification path to requested target

java - 在 catch block 中使用通用异常是否有任何负面影响