首页/系统/Windows 运维速查/场景:服务假死(无响应)排查

场景:服务假死(无响应)排查

服务进程在但功能停摆:先确认状态与端口,再看资源与日志,最后重启并保留现场。

Windows 运维速查系统更新于 2026-10-13

服务假死排查是什么

假死的典型特征:服务进程还在、SCM 显示 Running,但请求得不到响应,重启一次就恢复,过一阵又犯。这类问题通常不在服务本身,而在线程池耗尽、死锁、或依赖后端超时把工作线程占满。排查的目标不是尽快重启,而是在重启前把现场留住,否则同一个故障会反复来。

基本信息

现象特征SCM 状态为 Running 但功能无响应
第一判据状态查询正常、端口测试或应用请求超时
常见根因死锁、线程池耗尽、依赖后端不可达导致调用堆积
现场保留进程 dump、句柄数、线程状态、应用日志最后时间点
常用命令sc query、Test-NetConnection、Get-Process、Get-Counter

排查顺序

  • 确认服务状态:sc query 看是否为 Running,排除“进程在但已退出”
  • 验证端口与业务口:Test-NetConnection 测监听是否还能建连
  • 量资源:Get-Process 看 CPU、句柄数、工作集是否异常增长
  • 看线程与连接:确认线程数与已建立连接是否顶到上限
  • 查日志时间戳:应用日志与事件日志最后一条活动时间是否断档
  • 抓现场:资源与日志都指向卡死后,先做 dump 再重启

常用示例

常用示例
sc query MySvc | Select-String 'STATE'                       # 看服务状态
Test-NetConnection 127.0.0.1 -Port 8080                       # 端口还能不能建连
Get-Process -Name MySvc | Select-Object Id, CPU, Handles, WorkingSet64, Threads.Count   # 资源与线程
Get-Counter '\Process(MySvc)\Thread Count' -SampleInterval 2 -MaxSamples 5              # 线程数随时间变化
Get-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddHours(-2)} -MaxEvents 30 | Where-Object ProviderName -like '*MySvc*'   # 最近应用日志
Get-NetTCPConnection -OwningProcess (Get-Process MySvc).Id | Group-Object State            # 连接状态分布

指标与判读

指标正常表现异常含义
CPU 占用随业务波动持续 0 且请求超时=阻塞在等待
句柄数平稳或缓慢增长快速上涨多为句柄泄漏
线程数稳定在有限区间顶到池上限说明工作线程被耗尽
连接数随并发起落大量 Established 不释放提示下游超时
日志时间持续有新记录停在某时刻说明处理链路卡住
抓 dump 的价值在于能看清每个线程卡在哪一行代码:常见是等锁、等数据库连接、等下一条异步回调。没有 dump,事后只能靠猜。
做进程 dump 会短暂冻结目标进程(尤其大内存进程可能停顿数秒到数十秒),生产业务上要评估影响并在变更流程内执行。

易错点

  • 先重启后分析:现场一丢,同样的假死下次还会来,而且你仍然没有证据
  • 只看进程是否存活就判定正常,忽略了“进程活着但线程全被占满”这种最常见的假死形态
  • 重启服务前没检查依赖对象(数据库、消息队列、下游接口),结果重启后立刻又卡死
  • 把假死当成资源不足一味加内存,实际根因是死锁或连接池泄漏,加配置只推迟了复发时间

数据来源与参考

  • Microsoft Learn:sc query
  • Microsoft Learn:Test-NetConnection

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌