Windows SQL Server间歇性连接超时错误技术求助
已知背景
随机出现以下连接超时错误,重试即可成功;SQL Server及Windows日志无明显异常;已尝试重启服务器、检查TCP设置、调整保活时间,未解决问题。环境:Windows Server 2012、SQL Server 14.0.3401.7(2017)。
ERROR SqlServerHelper:759 - Unexpected exception
com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host *******, port 1433 has failed. Error: "Connect timed out. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall."
1. 升级JDBC驱动版本
SQL Server 2017(14.x)对应的旧版mssql-jdbc驱动可能存在连接超时处理的兼容性问题。建议升级至mssql-jdbc 12.x及以上版本,该版本对SQL Server 2017的连接稳定性有优化,修复了部分随机超时的bug。
2. 优化连接池配置(若使用连接池)
如果应用使用了连接池(如HikariCP、Apache DBCP),调整以下参数:
- connectionTimeout:设置为30000ms(30秒),避免因短时间网络波动直接触发超时
- validationQuery:配置为
SELECT 1,启用testOnBorrow或testWhileIdle,确保从连接池获取的连接可用 - maxIdleTime:设置为600000ms(10分钟),避免连接长期闲置被中间网络设备断开
- maximumPoolSize:根据服务器资源调整,避免超出SQL Server最大连接数限制(默认32767,实际受系统CPU/内存约束)
3. 排查中间网络设备的隐性限制
连接超时可能由服务器与客户端之间的网络设备(路由器、防火墙、负载均衡)触发:
- 联系网络团队检查设备的TCP闲置超时设置,确保其时长不短于SQL Server及客户端的保活时间
- 在Java客户端添加TCP保活相关配置:
- 通过系统属性设置:
System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("sun.net.client.defaultConnectTimeout", "30000"); System.setProperty("sun.net.client.defaultReadTimeout", "60000"); - 在JDBC URL中添加参数:
jdbc:sqlserver://<host>:1433;databaseName=<db>;loginTimeout=30;sendStringParametersAsUnicode=false;
- 通过系统属性设置:
4. 调整SQL Server及系统层面TCP保活参数
- SQL Server配置管理器:打开TCP/IP属性→IP地址标签,确保所有启用的IP的
TCP端口设为1433,TCP动态端口为空;切换至「高级」标签,确认「保持活动」已启用 - Windows系统注册表:修改以下键值(需重启服务器生效):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\ParametersTcpKeepAliveTime:设为300000(5分钟,单位毫秒)TcpKeepAliveInterval:设为1000(1秒,单位毫秒)TcpMaxDataRetransmissions:设为10
5. 排查服务器资源与SQL Server内部等待
- 性能监控:在超时时段用Performance Monitor监控服务器的CPU、内存、磁盘IO指标,排查是否存在瞬间高负载(如CPU100%、内存耗尽、磁盘IO延迟过高)
- SQL Server等待统计:执行以下查询,检查是否存在临时资源阻塞:
SELECT wait_type, wait_time_ms, signal_wait_time_ms, waiting_tasks_count FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'LCK_M_%' OR wait_type LIKE 'PAGEIOLATCH_%' OR wait_type IN ('RESOURCE_SEMAPHORE', 'LOGMGR_QUEUE') ORDER BY wait_time_ms DESC; - 启用扩展事件跟踪:创建扩展事件会话,跟踪
connection_failed事件,获取更详细的连接失败原因:CREATE EVENT SESSION [ConnectionFailures] ON SERVER ADD EVENT sqlserver.connection_failed( ACTION(sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.nt_username)) ADD TARGET package0.event_file(SET filename=N'ConnectionFailures.xel') WITH (STARTUP_STATE=ON);
内容的提问来源于stack exchange,提问作者lildazeez

