SQL Server连接报错10054:从网络层到内存压力的排查实践
2026/9/17 6:57:16 网站建设 项目流程

昨天下午,隔壁组的同事跑过来,一脸无奈地跟我讲:“我SSMS连不上开发库了,一点连接就报错,代码10054。”我当时还挺淡定,毕竟SSMS连SQL Server报错这事,十有八九是服务没起来、网络不通、或者防火墙挡了。结果上手一看,情况比预想的稍微绕一点,整个排查花了大半个小时,中间还走了一段弯路。今天把这次完整的过程写下来,包括排查思路、最终解决、以及几个容易被忽略的细节,给以后遇到同样问题的人一个参考。

这个错误代码10054在SQL Server的日常使用中不算高频,但一旦碰上,多数人第一反应是懵的。它不像登录失败那样给一句“sa密码错误”或者“用户被锁定”的明确提示,而是直接甩一个网络层的报错出来,看上去跟SQL Server没什么关系。但正因为这样,反而容易让人走偏,比如去改密码、重启网卡、重装客户端,全都试了一圈,问题还在。我这次就差点掉进这个坑里。


1. 报错10054到底代表什么

1.1 10054不是SQL Server的错,是网络层的错

先把这个错误码的本质说清楚。10054在Windows套接字编程里对应的是WSAECONNRESET,意思是“远程主机强迫关闭了一个现有的连接”。翻译成人话就是:你这边还在努力跟对方握手,对方直接“啪”一下把连接断了,连句再见都没说。

SSMS连接SQL Server走的是TCP/IP协议,所以这个报错本质上发生在网络层,而不是数据库引擎层。也就是说,错误产生的那一刻,SQL Server可能压根没来得及处理你的登录请求,连接就在更底层的TCP握手或SSL握手阶段被中断了。

这也是为什么很多人在网上搜10054,发现大家的解决方式五花八门。有人说是内存不足,有人说是防火墙问题,有人说是账号密码错误,还有人说是加密协议不匹配。表面看很混乱,其实是同一个底层错误在不同的环境下有不同的触发原因。所以遇到这个报错,最忌讳的就是瞎试,关键是把排查顺序理清楚。

1.2 常见的几个“假原因”,先别急着背锅

我在社区和论坛里转过一圈,发现大家对10054的讨论特别多,但有个普遍问题:很多人把自己猜测的原因当结论直接写在帖子里,导致后来的人跟着走弯路。我自己整理了一下,有几个高频出现的“假原因”,实际上很少是真正的主因。

第一个是“sa密码错误”。这个确实会导致登录失败,但密码错误时SQL Server会明确提示“用户登录失败”,错误码通常是18456,不会报10054。所以如果你看到的报错是10054,先把18656这个方向排除。

第二个是“SQL Server没有安装好”。如果服务根本没启动,SSMS会报“找不到服务器实例”或者“连接超时”,也不是10054。10054的典型特征是:连接发出去了,服务器也响应了,但在某一瞬间连接被强制重置。更像是“有回应但是被中途掐断”。

第三个是“SSMS版本太低”。版本不匹配确实会有兼容性问题,但通常表现为连不上、功能报错,也很少直接给10054。这次我们项目里的SSMS版本是20.x,SQL Server是2022,版本上完全匹配,所以这个方向也排除了。

搞清楚这些“不是原因的原因”之后,排查的路线就会清晰很多。接下来的章节我会按实际的排查顺序拆解,每一步都给出验证方法和判断标准。


2. 我这次的排查路线——一步步缩范围

2.1 先看服务活没活:SQL Server服务状态排查

遇到任何连接类问题,先确认操作系统层面的服务状态。这个步骤听起来基础,但恰恰是很多人跳过之后绕远路的地方。

Win + R输入services.msc打开服务管理器,找到名为SQL Server (MSSQLSERVER)的服务(如果你装的是命名实例,一般叫SQL Server (实例名)),看一下状态是不是“正在运行”。如果服务是停止状态,右键启动就行。如果启动失败,那问题可能出在配置层面,比如账户权限、配置文件缺失等,那是另一条排查线。

我这次检查的时候,服务状态是正常的,显示“正在运行”,启动类型是“自动”。也就是说,至少从服务视角看,SQL Server是活着的。但服务活着不代表能连上,就像门开了不代表屋里的人愿意搭理你一样,这个在后面才逐步暴露出来。

顺便提供一个技巧:在服务列表里查看“PID”列(需要先进入“详细信息”标签页),记下SQL Server进程的PID,后面查网络连接时会用到。这个我平时用习惯了,这次排查也帮了忙,在后面定位到具体进程时省了不少时间。

2.2 端口和防火墙:1433到底通不通

服务正常之后,第二步是确认网络层是否可达。SQL Server默认监听1433端口(如果你改了端口,以配置为准)。

我用管理员权限打开命令提示符,执行:

netstat -ano | findstr 1433

这条命令会列出所有跟1433端口相关的网络连接状态。正常情况下会看到一条:

TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 1234

注意看第三列的LISTENING状态,以及最后一列对应的PID。对比一下这个PID和刚才在服务管理器里记录的SQL Server进程PID,如果一致,说明SQL Server确实在1433端口上监听连接请求。

这里有个常见的坑是:SQL Server有两种监听方式,“全部监听”和“特定IP监听”。如果SQL Server配置管理器里只勾选了特定IP(比如一个内网IP),那么netstat里就不会出现0.0.0.0:1433这种全局监听,而是看到192.168.x.x:1433这种特定IP监听。这种情况并不算异常,只需要确保SSMS连接时用的是那个IP就行了。

我这次执行完netstat,结果是正常的,端口在监听。接着我又用telnet 127.0.0.1 1433测试本机回环地址,命令行没有提示无法连接,说明本机到数据库的网络链路基本是通的。

那问题出在哪?既然服务正常、端口正常、本地能通,就说明问题大概率在更高层。这时候我不再盲目猜,直接去翻SQL Server自己的日志,那里通常有最直接的线索。

2.3 日志才是老实人:翻SQL Server error log

SQL Server有自己的错误日志(Error Log),里面记录着每一次启动、关闭、连接成功、连接失败、内部错误等信息。这个日志比Windows事件查看器里的记录更详细,也更贴近数据库引擎的真实运行状态。

SSMS连不上,没关系,日志文件是存在磁盘上的。在默认安装路径下,可以通过以下方式找到:

默认实例的日志路径一般是:

C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Log\ERRORLOG

注意MSSQL16.MSSQLSERVER这个目录名里的数字会随版本变化。SQL Server 2022对应的是MSSQL16,2019是MSSQL15,2017是MSSQL14,以此类推。如果不确定自己机器上用的哪个目录,可以用文件资源管理器搜索ERRORLOG文件,或者用PowerShell执行:

Get-ChildItem -Path "C:\Program Files\Microsoft SQL Server\" -Recurse -Filter "ERRORLOG"

打开最新的ERRORLOG文件(不带时间戳的那个是最新的,带时间戳的是历史归档),我这次在里面看到了一条非常关键的记录,大意是:“某个连接被强行终止,原因可能是系统内存压力过大,或者客户端在登录过程中超时”。

这里就是排查的关键转折点。因为错误日志直接把问题指向了“内存压力”和“登录超时”,而不是网络不通或者端口没监听。到了这一步,我的关注点从网络层转向了服务器资源层。

2.4 证据链闭合:从事件查看器到进程分析

为了进一步确认内存压力这个方向,我又打开了Windows事件查看器(eventvwr.msc),在“Windows日志 -> 系统”里翻了翻。有些时候SQL Server因为内存压力触发的问题,会同时在这里留下一些警示记录,比如“系统检测到虚拟内存不足”之类的。

果然,我看到两条系统级别的警告,时间点跟我连接报错的时间基本吻合。再把任务管理器打开,看一下当前内存占用情况:物理内存16GB的机器,可用内存只剩不到2GB,CPU占用也长期在80%以上。开发机上同时跑着好几个IDE、本地服务、浏览器几十个标签页,再加上SQL Server默认会尽量占用大量内存作为缓冲池,系统的可用内存被挤到了一个非常危险的边缘。

到这里证据链基本闭合了:SQL Server在内存压力大的情况下,接收新连接时的握手过程异常缓慢,客户端等不及发起中断,服务器端也主动重置连接,最终表现为SSMS上的报错10054。这就能解释为什么服务正常、端口正常、本地telnet却全部通过,唯独SSMS连不上。


3. 实际解决过程:从定位到修复

3.1 释放资源后,重新配置内存上限

定位到问题是内存压力,第一步当然是释放内存。开发机嘛,能关的东西先关掉。我让同事把暂时不用的浏览器标签页关了,停掉了两个本地的小服务进程,可用内存从不到2GB恢复到了6GB左右。这一步操作之后,我试着用SSMS再次连接,结果依然报10054,但明显感觉报错前等待的时间变长了,说明服务器端已经在“挣扎”着响应握手请求。

既然临时释放内存不够,那就得给SQL Server上“紧箍咒”了。默认情况下,SQL Server的“最大服务器内存”配置是2147483647 MB,也就是不限制,它会根据自己的需要慢慢蚕食内存。在物理内存有限的开发机上,这个默认配置很容易跟操作系统和其他应用程序抢资源。

用管理员权限打开PowerShell,我通过sqlcmd来修改配置(因为SSMS连不上,就用命令行工具连):

sqlcmd -S localhost -E -Q "sp_configure 'show advanced options', 1; RECONFIGURE;" sqlcmd -S localhost -E -Q "sp_configure 'max server memory (MB)', 8192; RECONFIGURE;"

这两条命令的意义在于:第一条先把高级选项开关打开,第二条把SQL Server最大内存限制到8192MB(8GB)。这台机器物理内存有16GB,给SQL Server分一半,其余留给系统和应用,这是开发机上比较合理的比例。

如果你是第一次用sqlcmd,可能会发现系统提示找不到这个命令。这是正常的,sqlcmd是一个独立组件,通常和SQL Server命令行工具一起安装。在SQL Server 2022版本中,可以通过微软官方下载cmdline utilities安装包单独安装。如果不想装sqlcmd,也可以用PowerShell加载SQLPS模块后执行Set-SqlInstanceProperty,但操作上比sqlcmd复杂一点,这里就不展开了。

3.2 调整连接超时与worker threads参数

内存上限设置好之后,我又顺手调整了两个跟连接握手相关的参数:remote login timeoutmax worker threads

remote login timeout默认值是10秒,表示完成一次远程登录握手最多等待10秒。在服务器负载较高、内存吃紧的时候,10秒可能不够完成握手和认证,这个参数值得放大。我把它调到30秒,给慢速握手留出余量:

sqlcmd -S localhost -E -Q "sp_configure 'remote login timeout (s)', 30; RECONFIGURE;"

max worker threads默认是0,也就是由SQL Server根据CPU核心数自动决定。在CPU资源紧张的情况下,worker线程不够会导致新来的连接排队等不到处理,最终被重置。虽然自动模式在绝大多数场景下是合理的选择,但在开发机上这种同时跑很多应用、CPU又不够强的环境,手动给一个下限值(比如256或512)反而更能保证连接不被饿死:

sqlcmd -S localhost -E -Q "sp_configure 'max worker threads', 512; RECONFIGURE;"

顺带提醒一句:改了max worker threads之后不需要重启服务,执行RECONFIGURE就生效了,实测新连接马上就能用上调整后的配置。

3.3 重启服务并验证连接

参数改完之后,我通过服务管理器把SQL Server (MSSQLSERVER)服务重启了一次。重启的目的是让内存配置的调整彻底生效,也让缓存的连接池全部清空,确保新的连接走一遍完整的重新握手流程。

这里有个小技巧:重启服务之前,先在服务管理器里把启动类型设置为“自动”,确认下次开机也能自己起来,免得一台机重启之后SQL Server没启动,又白等半天。

重启完成后,我再次执行netstat -ano | findstr 1433确认端口监听了,然后打开SSMS,输入localhost(也可以用127.0.0.1或者机器名),选“Windows身份验证”,点击连接。这次连接过程明显顺畅了,一两秒内就成功连上了开发库。

为了确认不是运气好,我又连续断开重连了十几次,试了不同的数据库实例,还让同事在他自己的电脑上用SSMS远程连接测试,也都恢复了正常。到这里,问题算是彻底解决了。


4. 10054排查速查表:按场景对照

4.1 直接可用的checklist

这次排查的经验,我整理成一个速查表,下次遇到10054,不用再从头翻日志,直接按场景对照就行:

检查项验证方法正常结果如果异常的处理方式
SQL Server服务状态services.msc查看服务运行中启动服务或检查服务配置
端口监听netstat -ano | findstr 1433看到LISTENING确认SQL Server网络配置是否启用TCP/IP
本机连通性telnet 127.0.0.1 1433连接成功或光标闪烁检查防火墙入站规则
系统内存任务管理器可用内存大于2GB释放内存或调整SQL Server内存上限
SQL Server错误日志ERRORLOG文件无连接重置记录按日志提示定位
登录超时参数sp_configure 'remote login timeout (s)'10秒以上调大到20-30秒
加密连接设置SSMS连接选项-加密握手成功临时关闭加密或设置TrustServerCertificate=True

这张表里的每一项,都是我实际用过的检查手段,不是网上抄来的。有些情况下一个问题靠其中一项就能解决,有些则是多个问题叠加导致的,比如我这次就是“内存不足 + 默认超时太短”两个因素叠加。所以用这张表的时候,建议逐项检查,别跳过任何一项。

4.2 服务端配置参数的建议值

在开发环境的SQL Server上,有几个配置参数我建议直接设成下面的值,能减少很多幺蛾子:

max server memory (MB)设置为物理内存的50%-70%。比如16GB内存的机器,设置8192或10240。生产环境需要根据实际负载做更精细的计算,但开发机没必要纠结,给系统和应用留一半空间就行。

remote login timeout (s)设置为30秒。10秒默认值在正常网络环境下够用,但在大型查询或负载高峰时段,偶尔会因为握手慢而误报错误,调大到30秒基本能消除这类偶发问题。

user connections保持默认0(表示不限制)即可。这个参数在开发环境下如果误设得太小,会导致连接数超限,反而不容易排查。

一个需要注意的地方是,这些参数如果改错了,最坏的结果是SQL Server服务起不来,或者某些功能不可用。所以改之前最好先查询一下当前值,记录下来,万一出问题还能还原:

sqlcmd -S localhost -E -Q "SELECT name, value_in_use FROM sys.configurations WHERE name IN ('max server memory (MB)', 'remote login timeout (s)', 'max worker threads');"

这句查询会列出当前实际生效的配置值,以备对照。


5. 几个容易踩的坑和补充经验

5.1 SSMS版本与SQL Server版本的匹配问题

这次排查中虽然排除了版本因素,但这个问题在实际工作中碰到过很多次,值得单独说一句。

SSMS从18.x开始,版本号跟SQL Server的版本号就独立演进了。比如SQL Server 2022对应的SSMS版本是19.x及以上,目前最新稳定版是20.x。但注意,新版SSMS是可以连接老版本SQL Server的,比如SQL Server 2008 R2也能用SSMS 20.x来连,反过来不行——老版本SSMS连不上新版SQL Server。

如果你用的是很老的SSMS版本(比如17.x或更早),连接SQL Server 2022时报各种莫名其妙的网络类错误是很正常的。建议直接升级到当前最新版本的SSMS,这个工具是独立安装的,升级不影响现有数据库实例,风险很低。

5.2 是不是安全软件的“热情”干预

还有一个很容易被忽略的因素:本机安装的安全软件、上网行为管理软件、或者企业统一部署的终端防护工具,有时会主动拦截SSMS与SQL Server之间的连接。

这个我在另一台工作机上遇到过一次:SSMS连接一切正常,但每次执行特定查询时就会偶发10054。排查了很久,最后发现是终端防护软件检测到SSMS执行了某些SQL语法,以为是攻击行为,直接掐断了连接。后来在安全软件里把SSMS和sqlservr.exe加入信任列表,问题就消失了。

所以,如果上面那张速查表里的项目全查了一遍都没问题,但还是偶发10054,去翻一翻安全软件的拦截日志,说不定会有惊喜。

5.3 新版SSMS的加密连接与10054的纠缠

最后一个值得展开的是加密连接的问题。从SSMS 19开始,默认的连接加密方式是“强制加密”(Encrypt=Mandatory)。这意味着客户端和服务器之间必须完成TLS握手才能建立连接。如果服务器的证书有问题(比如自签名证书、证书过期、主机名不匹配),TLS握手就会失败,而失败的表现之一就是10054。

这个场景在本地开发机上尤其常见。SQL Server在安装时会生成一个自签名证书,正常情况下SSMS能够识别并信任。但如果证书过期了或者机器名改了(比如重装系统后改了计算机名),TLS握手就会失败。

遇到这种情况有两类解决办法。第一个是临时性的:在SSMS连接对话框左下角点击“选项”,在“连接属性”里把“加密”改为“可选”,或者勾选“信任服务器证书”。改完之后通常能马上连上,适合应急。

第二个是根治性的:重新配置SQL Server的证书。把新计算机名对应的证书导入到SQL Server的配置管理器里,然后在实例属性 -> 证书选项卡中选择正确的证书。这个过程需要重启SQL Server服务,操作前记得保存好当前工作。

我个人建议,开发环境可以直接在SSMS里勾选“信任服务器证书”,省事又高效;生产环境一定要走正规证书流程,别图省事跳过验证,安全不是小事。


这次排查10054的经历,让我又巩固了一遍“连接类问题先分层排查”的思路。很多时候我们一看到报错就急着上网搜解决方案,反而忽略了系统本身已经给足了线索,只是需要按顺序去看。日志、端口、服务状态、内存水位,这些数据组合起来,答案往往就在那里。

最后再分享一个小技巧:如果你经常在本地连接多个SQL Server实例,建议每次修改完服务端参数后,在SSMS里新建一个带“连接超时=30秒、执行超时=0(不超时)”的配置文件,存成.ssms文件放桌面。遇到连接问题时,先用这个慢速配置连一次,能有效避免因为超时设置太短导致的假性失败,也更方便判断是“真的连不上”还是“连得太慢”。

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

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

立即咨询