Java连接SQL Server显示SSL异常Caused by: java.io.IOException: SQL Server did not return a response.

Java连接SQL Server显示SSL异常Caused by: java.io.IOException: SQL Server did not return a response. The connection has been closed.

一、故事背景

最近有个项目需要从数据库中查到对应信息并通过企业微信机器人将信息推送出来,本来是一个很简单的需求,竟遇到了一个小插曲。拿到了数据库地址并被告知是SQL Server数据库,但是在通过程序进行数据库连接测试时发生了报错

二、具体报错信息

INFO  com.microsoft.sqlserver.jdbc.internals.TDS.Channel enableSSL 1651 - java.security path: /app/jdk/jre/lib/security
Security providers: [SUN version 1.8, SunRsaSign version 1.8, SunEC version 1.8, SunJSSE version 1.8, SunJCE version 1.8, SunJGSS version 1.8, SunSASL version 1.8, XMLDSig version 1.8, SunPCSC version 1.8]
SSLContext provider info: Sun JSSE provider(PKCS12, SunX509/PKIX key/trust factories, SSLv3/TLSv1/TLSv1.1/TLSv1.2)
SSLContext provider services:
[SunJSSE: KeyFactory.RSA -> sun.security.rsa.RSAKeyFactory
  aliases: [1.2.840.113549.1.1, OID.1.2.840.113549.1.1]
, SunJSSE: KeyPairGenerator.RSA -> sun.security.rsa.RSAKeyPairGenerator
  aliases: [1.2.840.113549.1.1, OID.1.2.840.113549.1.1]
, SunJSSE: Signature.MD2withRSA -> sun.security.rsa.RSASignature$MD2withRSA
  aliases: [1.2.840.113549.1.1.2, OID.1.2.840.113549.1.1.2]
, SunJSSE: Signature.MD5withRSA -> sun.security.rsa.RSASignature$MD5withRSA
  aliases: [1.2.840.113549.1.1.4, OID.1.2.840.113549.1.1.4]
, SunJSSE: Signature.SHA1withRSA -> sun.security.rsa.RSASignature$SHA1withRSA
  aliases: [1.2.840.113549.1.1.5, OID.1.2.840.113549.1.1.5, 1.3.14.3.2.29, OID.1.3.14.3.2.29]
, SunJSSE: Signature.MD5andSHA1withRSA -> sun.security.ssl.RSASignature
, SunJSSE: KeyManagerFactory.SunX509 -> sun.security.ssl.KeyManagerFactoryImpl$SunX509
, SunJSSE: KeyManagerFactory.NewSunX509 -> sun.security.ssl.KeyManagerFactoryImpl$X509
  aliases: [PKIX]
, SunJSSE: TrustManagerFactory.SunX509 -> sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory
, SunJSSE: TrustManagerFactory.PKIX -> sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory
  aliases: [SunPKIX, X509, X.509]
, SunJSSE: SSLContext.TLSv1 -> sun.security.ssl.SSLContextImpl$TLS10Context
  aliases: [SSLv3]
, SunJSSE: SSLContext.TLSv1.1 -> sun.security.ssl.SSLContextImpl$TLS11Context
, SunJSSE: SSLContext.TLSv1.2 -> sun.security.ssl.SSLContextImpl$TLS12Context
, SunJSSE: SSLContext.TLS -> sun.security.ssl.SSLContextImpl$TLSContext
  aliases: [SSL]
, SunJSSE: SSLContext.Default -> sun.security.ssl.SSLContextImpl$DefaultSSLContext
, SunJSSE: KeyStore.PKCS12 -> sun.security.pkcs12.PKCS12KeyStore
]
java.ext.dirs: /app/jdk/jre/lib/ext:/usr/java/packages/lib/ext
[2024-07-16 13:50:07.900]  ERROR com.alibaba.druid.pool.DruidDataSource run 2912 - create connection SQLException, url: jdbc:sqlserver://xxx.xx.xxx.xxx:1433;DatabaseName=weight, errorCode 0, state 08S01
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "SQL Server did not return a response. The connection has been closed. ClientConnectionId:941656ae-9767-4121-82b1-cb7ceef27a30".
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1667)
        at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1668)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
        at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
        at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:118)
        at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:232)
        at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:112)
        at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1703)
        at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1786)
        at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2910)
Caused by: java.io.IOException: SQL Server did not return a response. The connection has been closed. ClientConnectionId:941656ae-9767-4121-82b1-cb7ceef27a30
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.ensureSSLPayload(IOBuffer.java:651)
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.readInternal(IOBuffer.java:708)
        at com.microsoft.sqlserver.jdbc.TDSChannel$SSLHandshakeInputStream.read(IOBuffer.java:700)
        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.readInternal(IOBuffer.java:895)
        at com.microsoft.sqlserver.jdbc.TDSChannel$ProxyInputStream.read(IOBuffer.java:883)
        at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
        at sun.security.ssl.InputRecord.read(InputRecord.java:503)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
        at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1618)
        ... 10 common frames omitted

三、问题排查

  1. 确认网络环境畅通

    通过telnet ip 端口命令以及沟通负责网络的同事确认网络环境畅通

  2. 更换多个pom依赖版本无效

    一开始想当然的认为是依赖的版本问题,于是在这里花了大量时间进行测试

  3. 禁用SSL无效

    这里将url后面加上;encrypt=false;trustServerCertificate=true用于禁用SSL仍无效

四、问题解决

后续直接通过DataGrip进行连接测试,一开始测试连接也是报错
在这里插入图片描述

在点开Driver后看到有多个不同Dirver于是选择了jTds的驱动再试了下,竟然测试成功了。由此知道了问题所在。
在这里插入图片描述

那么我们先了解下这两种驱动程序有何区别

Microsoft SQL Server (jTds) 和 Microsoft SQL Server 驱动程序之间的主要区别如下:

Microsoft SQL Server (jTds)

开源:jTDS 是一个开源的 JDBC 驱动程序,支持 Microsoft SQL Server 和 Sybase。

性能:在某些情况下,jTDS 的性能可能优于 Microsoft 官方驱动程序,特别是在处理批量操作时。

功能:jTDS 支持的功能可能不如 Microsoft 官方驱动程序全面,特别是在新版本的 SQL Server 中。

社区支持:由于是开源项目,jTDS 的更新和支持主要依赖于社区贡献,更新频率可能较低。

Microsoft SQL Server (mssql-jdbc)

官方支持:这是 Microsoft 官方提供的 JDBC 驱动程序,专门为 SQL Server 设计和优化。

功能全面:官方驱动程序通常支持 SQL Server 的所有最新功能和特性,包括高级安全性、加密、集成身份验证等。

更新频率:官方驱动程序由 Microsoft 维护,更新频率较高,能够及时支持 SQL Server 的新版本和新特性。

兼容性:官方驱动程序在兼容性和稳定性方面通常表现更好,特别是在与其他 Microsoft 产品集成时。

选择建议

使用 jTDS:如果你需要一个开源解决方案,或者在特定场景下 jTDS 的性能表现更好,可以选择 jTDS。

使用 mssql-jdbc:如果你需要全面的功能支持、官方支持和更好的兼容性,建议使用 Microsoft 官方的 mssql-jdbc 驱动程序。

正确的pom依赖以及数据库url

<!--jtds驱动-->
<dependency>
    <groupId>net.sourceforge.jtds</groupId>
    <artifactId>jtds</artifactId>
    <!--选择合适的版本-->
    <version>1.3.1</version>
</dependency>
driver-class-name: net.sourceforge.jtds.jdbc.Driver
url: jdbc:jtds:sqlserver://xxx.xx.xxx.xxx:1433/weight
username: xx
password: xxxxxxx

更换了正确的依赖和url后报错即解决

如果你的sql server 2000远程连接时,无法打开1433端口,请按照以下顺序进行检查和修正: 1.如果你是win2003,那么一定要安装sql的补丁sp3a 检查你的SQL有没有打补丁,没有的话要打上补丁,检查的方法是在查询分析器中运行: select @@version 如果出来的版本号是8.00.760以下,则表明你未安装sp3的补丁,要装上. SQL补丁下载: 全部补丁的位置 http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=9032f608-160a-4537-a2b6-4cb265b80766 注意下载后,执行的时候是解压,要在解压后的目录中执行setup.bat才是真正的安装 2.SQL Server连接中的四个最常见错误: 一."SQL Server 不存在或访问被拒绝" 这个是最复杂的,错误发生的原因比较多,需要检查的方面也比较多. 一般说来,有以下几种可能性: 1,SQL Server名称或IP地址拼写有误 2,服务器端网络配置有误 3,客户端网络配置有误 要解决这个问题,我们一般要遵循以下的步骤来一步步找出导致错误的原因. ============= 首先,检查网络物理连接 ============= ping 如果 ping 不成功,说明物理连接有问题,这时候要检查硬件设备,如网卡,HUB,路由器等. 还有一种可能是由于客户端和服务器之间安装有防火墙软件造成的,比如 ISA Server.防火墙软件可能会屏蔽对 ping,telnet 等的响应 因此在检查连接问题的时候,我们要先把防火墙软件暂时关闭,或者打开所有被封闭的端口. 如果ping 成功而,ping 失败 则说明名字解析有问题,这时候要检查 DNS 服务是否正常. 有时候客户端和服务器不在同一个局域网里面,这时候很可能无法直接使用服务器名称来标识该服务器,这时候我们可以使用HOSTS文件来进行名字解析, 具体的方法是: 1.使用记事本打开HOSTS文件(一般情况下位于C:\WINNT\system32\drivers\etc). 添加一条IP地址与服务器名称的对应记录,如: 172.168.10.24 myserver 2.或在 SQL Server 的客户端网络实用工具里面进行配置,后面会有详细说明. ============= 其次,使用 telnet 命令检查SQL Server服务器工作状态 ============= telnet 1433 如果命令执行成功,可以看到屏幕一闪之后光标在左上角不停闪动,这说明 SQL Server 服务器工作正常,并且正在监听1433端口的 TCP/IP 连接 如果命令返回"无法打开连接"的错误信息,则说明服务器端没有启动 SQL Server 服务, 也可能服务器端没启用 TCP/IP 协议,或者服务器端没有在 SQL Server 默认的端口1433上监听.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值