智汇百科
霓虹主题四 · 更硬核的阅读氛围

分布式系统异常处理:常见问题与实战应对

发布时间:2026-01-16 23:40:23 阅读:229 次

服务调用超时,别急着重试

在微服务架构里,A服务调用B服务是家常便饭。某天早上刚到公司,监控就报警,订单创建成功率暴跌。查日志发现大量请求卡在用户中心接口,提示“Read timed out”。这时候第一反应可能是加个重试机制,但盲目重试只会让下游雪崩。

正确的做法是先判断超时原因。网络抖动?对方服务GC停顿?还是数据库锁住了?如果是后者,重试只会加剧数据库压力。可以在调用方设置熔断策略,比如连续5次超时就暂时拒绝请求,给系统喘息时间。

feign:\n  hystrix:\n    enabled: true\n  circuitbreaker:\n    enabled: true\n    requestVolumeThreshold: 5

数据不一致,靠补偿不如防患未然

转账场景中,扣款成功但积分没加,用户肯定炸锅。这种跨服务的数据断裂很常见。有人喜欢上Saga模式,每一步都配一个反向操作,像撤回转账、恢复余额。听起来完美,实际写起来漏洞百出——反向逻辑复杂,状态管理混乱,一旦补偿失败就得人工介入。

更稳妥的方式是在设计阶段就减少跨服务事务。比如把积分变动记录写入本地消息表,由定时任务逐步推送。哪怕接收方暂时挂掉,消息也不会丢。等它恢复后继续消费,最终达到一致。

INSERT INTO local_message (biz_id, type, status) \nVALUES ('order_123', 'add_points', 'pending');

日志分散,得会“串线”

一个请求经过网关、订单、库存、支付,每个服务都记了一笔日志。出了问题想查全过程,就得手动拼接trace ID。没有统一追踪体系的话,光找日志就能耗半天。

接入链路追踪工具不是选修课,是必修课。用SkyWalking或Zipkin,请求一进来就生成唯一traceId,透传到每个环节。点开页面直接看到整条调用链,哪个节点耗时高、是否出错,一眼看清。

节点宕机,心跳不能只靠感觉

集群里某台机器突然失联,是网络抖动还是进程崩溃?靠人工ping显然不行。注册中心如Nacos或Eureka要有健康检查机制。每隔几秒发个心跳,连续三次没回应就标记为下线,流量自动切走。

但也要小心误判。曾有个案例,服务因为Full GC停顿了10秒,心跳没及时发出,注册中心直接把它踢了。结果重启后又被迅速打垮。后来改成结合TCP连接状态和应用层探活,降低误杀率。