☰
JDBC连不上SQL Server 1433?从端口到安全组的全链路排查指南
2026/10/1 18:44:23 网站建设 项目流程

做后端开发的,八成都在某个晚上遇到过这么一条报错:The TCP/IP connection to the host xxx, port 1433 has failed。JDBC 配置好了、SQL Server 服务也开了,结果应用一启动,直接卡在数据库连接这一步。最气人的是,数据库服务器上明明还能用 SSMS 正常登录,旁边的同事也说“我用 Navicat 都能连上”,偏偏你的 Java 程序报 1433 端口连接失败。

这个报错说白了就是应用所在机器没能和 SQL Server 的 1433 端口建立起 TCP 连接,但背后的原因远不止“端口没开”这么简单。它可能藏在 SQL Server 实例监听配置里,可能被 Windows 防火墙拦掉,也可能出在云服务器安全组、JDBC 连接串参数、甚至是驱动版本和 TLS 加密策略上。我在这条 1433 连接链路上踩过的坑不算少,今天把多年排查经验整理成一篇可以直接照着查的文章,给正在跟端口连接失败搏斗的 Java 开发和运维朋友参考。

1. 为什么偏偏是 1433 端口连不上

1.1 从默认实例到动态端口:SQL Server 的监听逻辑

很多人对“1433”的理解就是“SQL Server 的端口”,这没错,但只说对了一半。SQL Server 安装的时候,默认实例叫MSSQLSERVER,这个默认实例默认监听在 TCP 1433 端口上;可如果你装的是命名实例,比如SQLEXPRESS、SQL2019,情况就完全不同了,命名实例默认采用“动态端口”,也就是每次 SQL Server 服务启动时,从系统可用端口里随机挑一个来用。

这带来的直观问题就是:你的 JDBC 连接串里写着jdbc:sqlserver://192.168.1.10:1433,可 SQL Server 实例实际监听的却是52033,你当然连不上。更麻烦的是,SQL Server 还存在一个叫“SQL Server Browser”的服务,它的作用是帮客户端解析“实例名对应的端口”。客户端如果不在连接串里写端口,而是写成jdbc:sqlserver://192.168.1.10\SQLEXPRESS这种形式,驱动就会去问 SQL Server Browser:这个实例在哪个端口?Browser 服务默认是禁用的,防火墙也不一定放行它依赖的 UDP 1434 端口,一问一个没回应,最终客户端就把锅甩给 1433 端口,报出连接失败。

所以,看到“1433 端口连接失败”,第一反应不要默认服务器一定在 1433 上监听。先搞清楚你连的是默认实例还是命名实例,是静态端口还是动态端口,排摸清楚再动手改配置。

1.2 常见报错形态:从错误文案判断故障方向

JDBC 连 SQL Server 的报错五花八门,常见文案有这么几种:

  • The TCP/IP connection to the host localhost, port 1433 has failed. Error: connect timed out
  • The TCP/IP connection to the host 192.168.1.10, port 1433 has failed. Error: Connection refused
  • The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption
  • Login failed for user 'sa'

这些报错都可以归到 1433 这条主题下,但排查方向完全不同。我把“连接失败”按时间顺序拆成三个阶段:TCP 能不能到、TLS 握不握得起来、SQL Server 认不认你这个登录账号。如果报错是Connection refused,意思是目标机器网络能通,但 1433 端口上没有程序在监听,你要去看 SQL Server 服务本身;如果报错是timed out,一般是防火墙、安全组或者路由策略把包丢了,数据包根本没抵达数据库;如果报错是 SSL 相关,说明 TCP 已经通了,但加密协商环节出了问题,属于证书和 TLS 配置问题。

用打电话来类比:Connection refused相当于号码拨过去,对方根本没有开机;timed out相当于电话在交换机那边一直没人接听、线路也不通;SSL 报错则相当于电话通了,但密保问题答不上来,对方不敢确认你身份。想清楚这一层,你就不会一看到“1433”就只知道去改防火墙。

2. 服务端逐项体检:SQL Server 到底监听在哪个端口

2.1 先在本地确认服务状态,别急着怀疑网络

排查任何连接问题,我都建议先从数据库服务器本机开始,因为这一步能把“数据库自身问题”和“网络链路问题”一刀切开。

打开服务器,先确认 SQL Server 服务有没有在运行。Windows 下按Win + R运行services.msc,找SQL Server (MSSQLSERVER),如果服务没起来,后面全白谈。服务状态看着是“正在运行”的话,再用本机命令行工具实测一下:打开命令提示符,执行

sqlcmd -S localhost -E

如果能进入1>命令行交互状态,说明 SQL Server 本机连接正常。没有 sqlcmd 的话,也可以用 SSMS 直接连localhost。本机都连不上,问题基本锁定在 SQL Server 实例本身;本机能连上,远程却不行,重点才转移到监听地址、防火墙和端口配置上。

接下来关键一步:看端口有没有真的监听。执行

netstat -ano | findstr 1433

正常情况会看到类似TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 1234的输出,最后的1234是进程 PID,再去任务管理器里确认这个 PID 是不是sqlservr.exe。如果这一行根本没有,说明 SQL Server 没有把服务监听在 1433 端口,那就进入 2.2 节的 TCP/IP 配置。

2.2 开启 TCP/IP 协议并固定 1433 端口的完整操作

SQL Server 安装完成后,如果只选了“命名管道”或“共享内存”协议,JDBC 是走不了 1433 的,因为 JDBC 驱动依赖 TCP/IP 协议。打开“SQL Server 配置管理器”,展开“SQL Server 网络配置”,找到你的实例,右侧协议列表里双击TCP/IP。

首先在“协议”选项卡中,把“启用”改成“是”。然后切到“IP 地址”选项卡,这里最容易踩坑。页面里列着 IP1、IP2、IP3、IPAll 等一堆条目,不少人只改了 IP1 的 TCP 端口,结果客户端走的是另一块网卡的 IP,照样连不上。稳妥的做法是:把每一个实际使用的 IP 的“已启用”都改为“是”,然后滚动到最下面的IPAll,在“TCP 端口”里填1433,把“动态 TCP 端口”里的数字清空,让实例固定监听 1433。

改完配置必须重启 SQL Server 服务,否则不会生效。在命令行执行:

Restart-Service MSSQLSERVER

如果是命名实例,服务名通常是MSSQL$SQLEXPRESS,注意对应替换。重启后再次执行netstat -ano | findstr 1433,看到LISTENING就说明端口起来了。另外顺手检查一下实例属性里的“连接”页,确保勾选了“允许远程连接到此服务器”。有些安全加固服务器会把这项关掉,远程连不上,本机却一切正常,很容易被误判成防火墙问题。

2.3 SQL Server Browser 服务:能不开就别依赖

我在前面提到,客户端用“主机名\实例名”方式连接时,需要通过 SQL Server Browser 服务查询端口。这个服务默认可能是禁用的,当你遇到 1433 失败,但netstat确实看到实例监听在别的端口时,很多人会陷入二选一:要么开 Browser,要么改固定端口。

我的建议是尽量把端口固定,不要依赖 Browser。开 Browser 不是不行,但你要额外放行 UDP 1434 端口,而且在多实例、多网卡环境下,它会引入更多变数。固定端口的好处是,JDBC 连接串里可以直接写host:1433,中间不经过任何查询解析,网络策略也好控制。实际操作中,我遇到过太多次“连接串里写了 instanceName,又顺手写了个 1433,两边打架”的情况。与其纠结实例名解析,不如老老实实统一用IP:端口直连。

3. 防火墙与网络链路:顺着 1433 找到拦路的“程咬金”

3.1 Windows 防火墙入站规则要这样配

服务端已经把 1433 监听起来了,远程还是连不上?第二站查 Windows 防火墙。很多时候安装 SQL Server 时会自动生成一条放行 1433 的规则,但如果你手动改过端口、装的是精简版、或者服务器组策略比较严,这条规则可能不存在。

打开“Windows Defender 防火墙”,选择“高级设置”,在左侧点“入站规则”,然后“新建规则”。类型选“端口”,协议选“TCP”,特定本地端口填1433;操作选“允许连接”;配置文件这一页里,按服务器所在网络位置勾选,我一般会勾上“域”和“专用”,公网网卡如果很少用,“公用”也可以勾上方便测试,但生产环境不建议把 1433 完全暴露到公网。规则命名成SQL Server TCP 1433,后面好辨认。

配置完以后,还有一件容易忽略的事:检查有没有其他规则把 1433 拒绝了。Windows 防火墙的规则不是“后建的允许规则一定能覆盖先建阻止规则”,如果规则列表里已经有某些安全软件写入的“阻止 1433”,新建的允许规则也可能被压住。临时验证时,可以先把这条入站规则停用再启用,看连接是否恢复;恢复后要一条条排查规则优先级,别图省事把整个防火墙关掉。

3.2 云服务器安全组和数据库白名单:本地化环境的重灾区

现在的服务器大部分在云上,Windows 防火墙之外,还有一层更隐蔽的关卡:安全组。我自己就踩过一个大跟头:数据库服务器上netstat看着一切正常,Windows 防火墙也加了规则,本地 telnet 自己通,但应用服务器怎么都连不上,最后发现云控制台安全组只放行了 80、443、3389 这几个端口,1433 压根没在入方向规则里。加了一条“TCP 1433 来源 IP 限定为应用服务器内网 IP”之后,连接立刻恢复。

如果你使用的是云数据库 RDS,而不是自己装的 SQL Server,那更简单,直接在 RDS 控制台的白名单设置里添加应用服务器的 IP。RDS 的白名单功能有时分为“经典模式”和“高安全模式”,高安全模式下不仅 IP 要白名单,端口一般也只能走默认值,所以遇到连接失败先去看白名单有没有加、加对没加对。

这里提醒一句,安全组的排查要分清“公网规则”和“内网规则”。如果应用服务器和数据库在同一个内网网段,要走内网 IP 和对应的内网安全组;如果应用在公网,要走公网入口,那更要注意是否允许 1433 被公网访问,不见得每个人都适合把数据库端口直接暴露在公网上。

3.3 用 telnet 和 PowerShell 主动验证端口通不通

与其靠猜,不如主动测一次端口连通性。在应用服务器上打开命令行,执行:

telnet 192.168.1.10 1433

端口通的话,屏幕会变成空白或者进入一个黑色窗口;失败则会提示“不能打开到主机的连接”。如果你的 Windows 没有安装 telnet 客户端,用 PowerShell 更方便:

Test-NetConnection 192.168.1.10 -Port 1433

重点看输出的TcpTestSucceeded,是True就说明 TCP 1433 通,是False就说明链路有问题。测试成功不代表 JDBC 一定能连上,但至少把范围缩小到了“端口可达”。反过来,如果netstat显示 SQL Server 监听在127.0.0.1:1433而不是0.0.0.0:1433,那说明服务只绑定到本机回环地址,远程网络的包根本到不了它,需要在 SQL Server 配置管理器的“IP 地址”选项卡里把对应网卡的“已启用”打开,重新帮它绑定到实际 IP 上。

4. JDBC 连接串与驱动:代码侧的坑一个比一个隐蔽

4.1 连接串参数逐个拆解,别再拼错分隔符

确认服务端端口没问题之后,再回头检查 JDBC 代码。微软官方驱动的连接串格式和 MySQL 差别很大,它用的是分号分隔,不是&:

jdbc:sqlserver://192.168.1.10:1433;databaseName=testdb;user=sa;password=your_password;loginTimeout=15;connectTimeout=15;encrypt=false;trustServerCertificate=false

databaseName指定默认数据库;loginTimeout和connectTimeout建议显式设置,否则应用可能会在 TCP 层长时间挂起。encrypt参数在后面详细讲,这里先记住它的默认行为在新版本驱动里已经改成true,老项目经常在这一步翻车。

还有一种写法是使用命名实例,形如:

jdbc:sqlserver://192.168.1.10;instanceName=SQL2019;databaseName=testdb

这个写法的前提是 SQL Server Browser 可用、UDP 1434 放行。如果你已经在用IP:端口直连,就不要同时再写instanceName,两者混用会让解析逻辑变得复杂。我个人在生产环境一律推荐固定端口 +IP:1433,省掉一半的理解成本。

4.2 驱动版本没选对,连接也可能直接失败

JDBC 驱动报错时,很多人的第一反应是查 SQL Server,但问题也可能出在mssql-jdbc驱动版本和 JDK 不匹配上。微软官方驱动的 Maven 坐标是这样的:

<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>12.4.2.jre8</version> </dependency>

注意 artifact 版本号里的jre8后缀,它表示这个包适用于 Java 8 运行时。如果项目用的是 JDK 17,应该选jre11或更新版本的驱动,否则可能出现类加载异常或者底层 TLS 协商失败。老项目还在用sqljdbc4.jar的话,最好也换成官方新版本,老驱动连新版本 SQL Server 有时会出现不兼容的报错。判断办法不复杂:本地用一个小main方法跑一段Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"),再打印驱动版本,和 Java 版本对照一下,基本能定位。

4.3 身份验证模式、SA 账号和 sqljdbc_auth.dll 的恩怨

有时候报错已经变成了Login failed for user 'sa',却还有人管它叫“1433 端口连接失败”,因为日志里上一行可能确实有 1433 字样。其实这时候 TCP 已经通了,卡在登录认证。要检查的点有三个:

第一,实例身份验证模式是不是“SQL Server 和 Windows 身份验证模式”。如果是纯 Windows 身份验证,用user=sa这种 SQL 账号登录一定会失败。在 SSMS 里右键实例属性,安全性页面可以改,改完要重启实例。

第二,sa账号本身是否被禁用、密码是否过期。SQL Server 出于安全考虑,很多版本默认禁用sa,你需要显式启用并设置一个强密码。

第三,如果用 Windows 集成身份验证,连接串里要写integratedSecurity=true,并且把微软 JDBC 驱动包自带的sqljdbc_auth.dll放到java.library.path里。这里有个很经典的坑:JVM 是 64 位,放进去 32 位的sqljdbc_auth.dll,启动时不会报错,一执行连接就抛异常,折腾半天才发现是位数不对。

4.4 SSL/TLS 加密导致连接失败:最容易被忽略的一环

从报错日志看,The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption这条并不罕见,但它和“1433 端口连接失败”经常一起出现,误导了好多人。实际上 TCP 1433 已经通了,问题是新版本微软 JDBC 驱动默认把encrypt设为了true,而 SQL Server 自带的证书通常不被 JDK 信任,TLS 证书校验不过,连接就失败了。

测试环境最简单的处理方式是在连接串里加上:

encrypt=false;trustServerCertificate=true

encrypt=false是关闭 TLS 加密,trustServerCertificate=true是让驱动不校验服务器证书链。但对生产库来说,把加密关掉并不可取,更好的做法是给 SQL Server 配置一个受信任的正式证书,并把证书导入到运行 Java 程序的 JDK 信任库中。判断问题是不是出在证书这儿,方法很简单:先用encrypt=false;trustServerCertificate=true试连,如果立刻通了,那问题基本锁定了。

5. 实际问题排查:一份可以直接抄检查单

5.1 从应用机器到数据库服务的分层排查步骤

把前面所有知识点串起来,我平时排查 JDBC 连 SQL Server 1433 失败的固定顺序是六步:

第一步,在数据库服务器本机用sqlcmd -S localhost -E测连接,确认 SQL Server 本身没坏。

第二步,执行netstat -ano | findstr 1433,看 SQL Server 是否监听在 1433,监听地址是不是0.0.0.0。

第三步,在应用服务器执行Test-NetConnection 数据库IP -Port 1433,判断 TCP 链路通不通。

第四步,如果链路不通,逐层检查 Windows 防火墙、云安全组、RDS 白名单、内部网络路由策略。操作顺序没有统一标准,但我习惯先看云安全组,再看 Windows 防火墙,因为云上环境出问题的概率最高。

第五步,如果链路通了,再回到代码侧,用一个最小 JDBC 测试类验证,加上loginTimeout参数防止应用挂死。

第六步,如果 JDBC 报错还是带着 1433,打开 SQL Server 错误日志,看是 TLS 握手失败,还是登录失败,还是端口根本拒绝。这一步能直接定位到身份验证或者证书问题上。

5.2 两个真实问题复盘:一个假象,一个真拦路

第一个案例是“假象”。公司有个项目用 SQL Server 2019 命名实例,开发环境一直正常,上了测试环境后 JDBC 连接串写的还是jdbc:sqlserver://10.20.30.40:1433;instanceName=TEST,结果报 1433 失败。上去一看,netstat里根本没有 1433,实例实际监听在 52033 动态端口,而 SQL Server Browser 服务又没开。最后我把 TCP/IP 的IPAll端口固定成 1433,重启服务,再把连接串里的instanceName去掉,问题消失。这个案例里,1433 只是个“背锅”的数字,真正的问题是端口没有固定下来。

第二个案例是“真拦路”。一个部署在云上的 SQL Server 2016,Windows 防火墙规则全加了,服务器本机测试正常,应用服务器 telnet 却一直超时。排查到最后,云控制台的安全组入方向完全没有 1433 这条规则,加上之后立刻通了。这个案例看起来简单,却是最容易被忽略的,因为很多人默认云服务器只有 Windows 防火墙一关,忘了安全组在操作系统外部还有一层控制。

5.3 问题速查表:按症状找原因

现象最可能原因验证方法解决动作
Connection refusedSQL Server 服务未启动,或 TCP/IP 协议未启用,或端口不是 1433服务器上执行netstat -ano | findstr 1433启动服务,开启 TCP/IP,固定端口为 1433 并重启实例
Connection timed outWindows 防火墙、云安全组或网络策略阻断应用服务器执行Test-NetConnection IP -Port 1433检查防火墙入站规则、云安全组、RDS 白名单
本机可连,远程不可连SQL Server 监听在 127.0.0.1,或远程侧防火墙未放行netstat -ano | findstr 1433查看监听地址在 TCP/IP 的 IP 地址选项卡启用对应网卡
命名实例一直报 1433 失败实例使用动态端口,SQL Server Browser 未开启netstat -ano查看实际监听端口固定端口,连接串直接使用IP:端口
SSL 报错证书不受信任或 TLS 版本不匹配临时添加encrypt=false;trustServerCertificate=true测试正确配置证书或导入 JDK 信任库
Login failed for user身份验证模式不是混合模式,或账号被禁用SSMS 检查实例属性和账号状态启用混合模式,启用 sa 账号并重置密码

我个人排查这类问题时,第一件事永远是先把“端口通不通”和“实例监听在哪”分开。很多告警写着 1433,但实际数据包根本没到 SQL Server,或者 SQL Server 端口压根不是 1433。只要守住这个思路,大部分问题都能在半小时内定位。最后再分享一个小技巧:连接串里加loginTimeout=15真的很有用,它能把“连接失败”从应用假死变成一次快速报错,早报错早定位。希望这篇经验能让你下次再看到 1433 的时候,不再一头雾水。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询