Java SNI 扩展被禁用导致的阿里云大模型服务请求异常

服务器请求阿里云大模型服务总是报“Remote host terminated the handshake”异常,从日志看是 SSL 握手出现异常。多方排查未能锁定问题,经过分析 SSL 握手日志,发现是 SNI 问题。对历史代码进行分析,竟是某个角落处禁用了 SNI 扩展。

异常现象

服务器请求阿里云大模型服务总是报“Remote host terminated the handshake”异常,从日志看是 SSL 握手出现异常。

org.springframework.web.reactive.function.client.WebClientRequestException: Remote host terminated the handshake
Caused by: org.springframework.web.reactive.function.client.WebClientRequestException: Remote host terminated the handshake
        at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)
        Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below:
Error has been observed at the following site(s):
        *__checkpoint ⇢ Request to POST https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation [DefaultWebClient]
Original Stack Trace:
                at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)
        ......
Caused by: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
        at java.net.http/jdk.internal.net.http.common.SSLTube.checkForHandshake(SSLTube.java:595)
       ......
Caused by: java.net.SocketException: Connection reset
        at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:401)
        at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:434)
        ......

问题锁定

通过增加 Java 启动参数,打印 SSL 握手日志,发现是缺少“server_name”。

本地机器可以正常请求,ClientHello 如下:

"ClientHello": {
  "client version"      : "TLSv1.2",
  "extensions"          : [
    "server_name (0)": {
      type=host_name (0), value=dashscope.aliyuncs.com
    },
    "status_request (5)": {
      "certificate status type": ocsp
    }
  ]
}

服务器如下,缺少“server_name”。

"ClientHello": {
  "client version"      : "TLSv1.2",
  "extensions"          : [
    "status_request (5)": {
      "certificate status type": ocsp
    }
  ]
}

经过各种排查,发现历史遗留代码中有如下代码行。2016 年为了解决部分网银不支持 SNI 问题,禁用了 SNI 扩展。时过境迁,当时的历史问题已经消失,却阻挡了阿里云的大模型请求。

System.setProperty("jsse.enableSNIExtension", "false");

本站简介

聚焦于全栈技术和量化技术的技术博客,分享软件架构、前后端技术、量化技术、人工智能、大模型等相关文章总结。