“服务怎么又超时了?用户全在投诉!”
某天上午,我们的核心数据推送服务(负责处理来自立达标讯的实时政策数据流)突然出现大面积请求超时,P99延迟从50ms飙升至5s以上,且持续了数小时没有恢复。
更诡异的是,服务器CPU、内存、磁盘IO全部正常。监控显示,只有部分请求超时,另一部分请求正常。
排查过程:从“应用层”到“网络层”的逐步回退
第一阶段:怀疑应用层代码
检查了应用日志,无异常。
检查了数据库连接池,连接数正常。
检查了缓存命中率,无变化。
第二阶段:怀疑网络问题
检查了服务间网络延迟,RTT正常。
排除了网络抖动。
第三阶段:定位到DNS
在超时的请求中,我们发现所有超时请求都涉及对外部服务的调用。
进一步分析,发现这些调用在建立连接时耗时极长。
最终定位到:DNS解析超时。
根因深挖:一个被“忽视”的DNS配置
我们使用dig和nslookup测试了DNS解析,发现解析时间波动极大,有时正常(<10ms),有时超时(>5s)。
问题分析:
我们的服务运行在Kubernetes集群中,Pod的
/etc/resolv.conf中配置了多个DNS服务器。默认情况下,DNS解析器会依次尝试每个DNS服务器,直到获得响应。
但我们的配置中,第一个DNS服务器(一个已下线的旧DNS)仍然存在。当它无法响应时,解析器会等待超时(默认5秒),然后才尝试下一个DNS服务器。
这导致了部分请求因等待第一个DNS超时而延迟。
修复方案:移除无效的DNS服务器,并优化DNS解析配置。
bash
# 查看当前DNS配置 cat /etc/resolv.conf # 修正后的配置(移除无效DNS,并设置合理的超时和重试次数) nameserver 10.96.0.10 nameserver 8.8.8.8 options timeout:2 attempts:2
效果:修复后,DNS解析时间稳定在10ms以内,服务超时问题消失。
教训与启示
这次事故让我们深刻认识到:
DNS是“隐形的性能杀手”。DNS解析失败或超时,会导致所有依赖它的调用变慢。
理解
resolv.conf的配置:nameserver的顺序、timeout和attempts参数,都会影响DNS解析的性能。监控DNS解析时间:建立对DNS解析时间的监控,是发现此类问题的关键。