在分布式系统中,一个服务的缓慢或故障很少局限在自身。一次简单的超时可能触发反复重试,重试消耗线程池资源,线程池耗尽又导致上游请求排队,最终引发级联崩溃。这类系统性故障——级联故障、重试风暴、超时不匹配——是微服务架构中的“隐形杀手”,它们没有单一异常堆栈,却能将局部抖动放大为全站宕机。
本文将基于线程转储、分布式追踪和指标监控,展示如何诊断这些模式,并给出设计层面的预防建议。
级联故障:线程池耗尽与锁等待
级联故障的典型表现是上游服务线程池耗尽。假设支付服务(Payment)因数据库慢查询导致响应时间从 20ms 飙升至 2s,此时调用支付服务的订单服务(Order)会保持 HTTP 连接等待响应。如果订单服务的线程池大小为 200,2 秒内新请求持续涌入,线程池迅速被占满,后续请求要么排队要么直接拒绝。更糟糕的是,订单服务本身又调用库存服务(Inventory),因线程池已满,库存请求也被阻塞——故障从支付服务向上游一层层传播。
通过线程转储诊断
当线程池耗尽时,线程转储(Thread Dump)会显示大量线程处于WAITING(park)或TIMED_WAITING状态,等待某个锁或连接。例如:
"http-nio-8080-exec-123" #123 daemon prio=5 os_prio=0 tid=0x00007f1234000 nid=0x2a4b waiting for monitor entry [0x00007f122fbfe000] java.lang.Thread.State: BLOCKED (on object monitor) at org.apache.tomcat.util.net.SocketWrapperBase.waitForSending(SocketWrapperBase.java:136) - waiting to lock <0x000000076e7a9a10> (a org.apache.tomcat.util.net.NioEndpoi