资讯动态

从IP地址入手排查线上故障:一次完整链路追踪复盘

发布时间:2026/9/28 5:44:50 来源:尧图企业网站定制
凌晨两点四十手机连着震了十几次我爬起来看了一眼告警群线上服务成功率掉到65%响应时间已经逼近十秒持续了快二十分钟。我第一反应不是打开日志追堆栈而是先问了句自己——现在进来的流量到底是从哪个IP来的这个习惯是我踩过好几次坑之后才养成的。很多人遇到线上故障下意识就冲进应用日志里找exception找来找去半天最后发现根本不是代码问题。IP地址听起来是个再基础不过的网络概念但在关键时刻它往往是最先开口说话的“目击证人”。这篇复盘我想完整记录一下Zabbix/Nginx日志、ss/netstat连接状态、whois归属查询这些手段是如何一环扣一环在一个看似莫名其妙的线上故障里把真正的根因给揪出来的。适合刚好遇到“服务突然不可用、成功率莫名下跌、重启也解决不了”这类问题的人看也适合刚接触运维、后端开发想建立故障排查方法论的同学参考。我不打算上来就告诉你答案而是把当时的排查路径原封不动复现一遍包括中间走错的方向和最后反转的瞬间。1. 故障现象与第一轮排查1.1 告警长什么样从监控指标说起这次故障的业务场景不算复杂一个对外提供API的服务前边是Nginx做负载均衡后边挂着四台应用服务器。监控看板上的信号非常明确API成功率从99.9%开始往下掉最低掉到62%左右平均响应时间从80ms直接飙到9.8s错误码集中在502和504。但有一个细节很有意思四台应用服务器里的三台负载指标完全正常CPU、内存、流量都没有明显波动只有一台机器的网络连接数异常地高。我当时的第一判断跟大多数人一样肯定又是哪次发布有问题。于是先去查了最近的发布记录结果显示没有任何新代码上线也没有配置变更。这就有点意思了没有发布没有变更服务却大面积超时和连接失败说明问题大概率不在应用代码本身而是在请求链路某个环节上。这个时候如果继续盯着日志翻堆栈大概率是浪费时间更好的做法是把视角收回来从连接层和网络层开始问问题请求从哪来经过了哪些IP到了哪台机器1.2 我第一反应之前踩过的坑说实话以前遇到线上故障我的第一反应也是开日志、看堆栈、搜关键字结果有一次查了三个小时最后发现是上游服务把请求打到了一个已经被摘除的节点上日志里什么异常都没有只有一堆连接超时。那次之后我给自己定了一条规矩线上故障首选排查路径永远是“流量入口 - 网络链路 - 连接状态 - 应用日志”顺序不能乱。为什么先看链路和连接因为应用日志只能告诉你“我这台机器内部发生了什么”但它没法告诉你“为什么请求会走到这台机器”。而IP地址和端口状态恰恰是串联整条链路的线索。比如一个请求从客户端到Nginx再到后端每一跳都会留下源IP和目标IP的痕迹。只要把这条链路捋直了大部分“莫名其妙”的故障都能从链路中间找到异常点。反过来如果一上来就钻到日志里很容易被错误日志的数量误导以为系统哪里都坏了其实只是入口流量被导向了一个异常的目标而已。2. 从域名到IP把访问链路摊开来看2.1 从DNS解析开始IP地址的第一层身份排查的第一步我先确认了入口域名的解析结果是否正确。我们的服务对外域名是 api.example.com正常情况下应该解析到负载均衡的VIP虚拟IP再由VIP转发给后端节点。我直接在跳板机上执行了下面这组命令dig short api.example.com nslookup api.example.com解析结果返回了一个IP一看就是内网地址10.20.30.4。这个IP是我们Nginx集群的VIP看起来没什么异常。但紧接着我又做了一次测试从一台公网测试机去解析同一个域名发现返回的结果竟然也是10.20.30.4这就有点不对了。我们的架构里公网用户访问应该先经过云上的公网负载均衡再转发到内网的Nginx VIP正常情况下公网解析不会直接暴露内网IP。也就是说要么是DNS配置被改过要么是某些调用方绕过了公网入口直接拿着内网IP在访问。现在回看这个细节是整个排查路上第一个真正有价值的线索——IP地址在那一刻已经不止是一个数字它在告诉我访问链路的入口可能被“偷换”了。但因为当时线上告警还在持续我没有在DNS上逗留太久只做了个临时记录就继续往下追连接状态了。2.2 本机连接状态ss命令告诉我谁在连我第二步我登上了那台连接数异常高的应用服务器用ss命令看了一眼实时的网络连接。说实话我之前一直用的是netstat后来发现ss在处理大量连接时速度更快输出格式也更清晰在故障现场那种环境下快一秒是一秒。我执行的是ss -antp | grep :8080 | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -nr | head -20这条命令的意思很简单列出所有和目标端口8080建立的TCP连接提取对端IP统计每个IP的连接数量从高到低排前20个。输出结果里绝大多数来源IP都集中在几个熟悉的网段但有一个IP非常扎眼192.168.7.19单独占了将近四千个ESTABLISHED连接。一个正常业务调用方不可能同时和同一台后端建立四千多个TCP长连接这明显超出了合理范围。我顺手又看了下TIME_WAIT和SYN_SENT状态的数量TIME_WAIT大概几千个不算太离谱但SYN_SENT异常多达到两百多个这说明这台服务器在频繁向外发起连接而且很多连不上。一个以接收请求为主的应用服务器向外SYN_SENT数量激增通常意味着它在做某种回调、上报或者干脆是被某个恶意脚本当成了“跳板”。到这里IP地址已经从“一个冷冰冰的数字”变成了“一个有犯罪嫌疑的地址”。3. IP地址如何一步步交代自己的来源3.1 区分公网IP与内网IP先给IP分类当192.168.7.19这个IP出现后我先给IP做了一次归属判断。这一步看起来基础但真的会有人在这一步翻车。简单说IPv4地址可以按用途分成几个大类私有地址段包括10.0.0.0/8、172.16.0.0/12、192.168.0.0/16这些只能在局域网内使用公网路由不可达剩下的才是公网地址需要向运营商或云厂商申请后才能对外提供服务。我把常见地址段整理过一份速查表故障排查时直接用强烈建议人手一份地址段类型用途说明127.0.0.0/8回环地址本机自检网络调试常用10.0.0.0/8私有地址A类大型企业内网、云上VPC容量大172.16.0.0/12私有地址B类企业内部网、容器集群、K8s Service网段192.168.0.0/16私有地址C类办公室网络、家庭路由器、小型局域网169.254.0.0/16链路本地地址DHCP获取失败时自动分配出现这个多半网络配置有问题其余IPv4地址公网地址需向运营商或云厂商正式申请可全球路由192.168.7.19 属于C类私有段毫无疑问是我们内网里的某台机器。但内网私有IP到处都是光知道这个还不够。我接着用whois和IP归属库做了进一步确认结果发现它是VPC里一个不常用的网段对应的是数据同步服务集群里的机器。你别小看这一步光是判断“这个IP是不是自己的资产”就能省下大量时间不然你可能会跑到云上查一堆公网IP的归属查半天发现跟自家业务半毛钱关系没有。3.2 从单个IP扩大范围用IP做流量聚簇单个IP异常不一定能说明问题所以我决定把范围放大从这台应用服务器的整个访问日志里把所有来源IP按连接数和请求数聚合了一遍。这一步的目的是看“异常流量到底是孤例还是有组织的一群IP”。我用了awk分析Nginx的access log命令大概是awk {print $1} /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -30输出很快出来了排在前面的不止192.168.7.19一个还有另外十几个IP全部集中在192.168.7.0/24这个C段连接量从几百到几千不等。一个C段里的十几台机器在同一时间集中访问同一台后端而且访问模式高度相似这不像正常的业务交织更像一个完整的子系统在向这台机器疯狂地“灌流量”。这时候IP地址的第二个价值体现出来了它能在不依赖应用日志的前提下帮你把“肇事流量”画出一个轮廓。我顺藤摸瓜查了这些IP对应的服务器业务角色发现它们都属于一个批处理任务集群平时承担数据清洗和同步工作但按架构设计这个集群根本不应该直接访问8080端口。真正的异常点慢慢浮现了——流量来源确认了接下来就该搞清楚它们为什么要打到这里来。4. 找到IP后的一切从网络层逼近应用层4.1 用IP反向定位调用方查配置、对架构追到192.168.7.0/24这个C段之后我反查了一遍这些机器上的应用配置。在其中一个批处理节点的配置文件里我找到了一个让人眼前一黑的操作它的任务调度地址写的是一个旧的服务发现地址而这个旧地址的解析结果竟然指向了那台连接数异常的应用服务器。说白了就是批处理集群本来要调用数据中台的服务但由于服务注册中心里残留了一条历史健康检查记录它们拿到的服务实例IP是已经“退役”的旧节点而旧节点的IP后来被重新分配给了现在这台上线的应用服务器。结果就是所有本该打到数据中台的请求全被硬塞到了这台应用服务器上应用根本没有承载这个流量的能力连接全部堵塞进而拖垮了整个服务。IP地址在这里起到了一个反向定位器和“记忆载体”的作用。它记录下了服务注册中心的历史信息记录下了网络转发路径的错位这些信息在应用层日志里是完全看不出来的因为接收请求的应用本身并没有报错它只是处理不过来。4.2 顺着IP看端口、协议、进程确认了来源IP之后我又回头补了一个关键操作在应用服务器上用ss命令查看这些连接对应的本地进程确认到底是哪个进程在接收。我当时用了这条命令ss -antp | grep 192.168.7.19 | head -5输出里能看到本地端口8080对应的进程PID再用ps确认进程名结果发现接收连接的是一个我们内部框架的HTTP服务进程但它暴露的端口和配置文件里的端口并不完全一致。这个问题单看IP发现不了单看进程也发现不了必须把“IP端口进程”三个维度拼到一起才看得全。这一环节我最想强调的一点是不要只看IP是谁还要看IP和谁配对。一个IP可以对应多个进程一个进程可以监听多个端口如果你只过滤IP不关联端口和进程最多只能找到“谁在访问”找不到“访问到了哪个应用”。正确做法是先用ss -antp把IP、端口、进程三元组全部拉出来再去对应用配置任何一步漏了都容易误判。4.3 真正的根因IP绑定导致流量误入到这里我已经能拼出完整故事了批处理集群通过服务注册中心获取目标地址但注册中心里一个过期实例注册信息指向了一个已被回收的IP。这个IP现在是应用服务器的地址于是请求全部误入。更隐蔽的是由于应用服务器上某个组件启动时通过配置绑定了一个旧的虚拟IP导致部分返回包里源IP显示成了另一个不相干的地址这让前几步的排查一度被带偏。根因总结起来就是一句话IP地址管理混乱服务注册信息没有自动清理机制加上应用启动配置里写死了一个废旧IP。三件事单独看都不致命串在一起就成了一个能让人排查通宵的线上故障。修复动作其实不复杂摘除异常连接更正服务注册中心的实例信息修改应用启动配置让端口绑定从配置文件读取而非硬编码旧IP。回滚之后流量立刻恢复成功率回到99.9%前后花了不到半小时。5. 常见问题与排查技巧实录5.1 一套顺手命令组合这次故障里用到的命令组合我后来整理成了一套固定的排查顺序每次遇到类似问题就直接套用。先用dig确认域名解析和安全入口然后用ss统计连接接着用awk分析日志最后用whois或IP归属库确认IP身份。# 第一步确认DNS解析结果 dig short api.example.com # 第二步查看本机监听端口、连接数量统计 ss -lntp ss -antp | grep :8080 | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -nr # 第三步分析Nginx访问日志按来源IP聚簇 awk {print $1} access.log | sort | uniq -c | sort -nr | head -30 # 第四步确认IP归属whois查询公网归属内网IP查资产平台 whois 8.8.8.8这套组合的核心思路是“由外而内”先确定入口地址对不对再看连接进来没有然后看流量来自哪些IP最后才轮到看日志定位业务层问题。只要不跳步基本不会走太偏。5.2 三个容易看走眼的地方第一个容易看走眼的是NAT和代理。很多内网请求经过NAT网关后来源IP会统一变成网关出口IP如果你只看来源IP会以为是同一个客户端在刷流量其实是几百个客户端共享出口。第二个是VIP和浮动IP高可用集群里经常会有一个IP在多台机器间漂移光看IP地址本身没法定位物理机必须配合ARP表或者云平台的API查实际绑定关系。第三个是IPv6很多新服务已经开始启用IPv6地址你如果不把IPv6的连接状态纳入统计会漏掉一部分流量。顺着这三个点展开我们在复盘时还发现一个细节当时我们有一批服务已经支持IPv6但监控和日志分析工具只统计了IPv4导致IPv6的流量一直处于“盲区”。好在这次故障的流量主要是IPv4不然排查起来还要多转好几个弯。5.3 排查避坑心得IP地址要当“动态证据”看待这次之后我给团队定了几条硬规矩。第一线上故障排查时凡是涉及“某IP异常”的判断必须同时附上时间点、端口、协议、进程四个维度不能只甩一个IP出来。第二所有服务注册信息必须设置TTL和健康检查失败自动摘除避免过期实例长期留在注册中心里“诈尸”。第三应用的网络配置文件一律禁止硬编码IP全部改为通过环境变量或配置中心下发至少也要有自动化校验防止“旧IP被重新分配”这种坑再次出现。我也理解在紧急故障时做到这些并不容易人一慌就容易跳过步骤。但恰恰是这种时候IP地址这种最基础的信息越能帮你稳住心态。它不像日志里千奇百怪的异常信息它的格式是固定的、可校验的、可追踪的。只要你愿意多花几秒钟去查它一下它几乎不会撒谎。5.4 故障复盘清单速查这次故障之后我在复盘清单里新增了几项固定检查内容每次出问题都会先过一遍域名解析结果和实际服务架构是否一致有没有多余的历史记录内网资产平台里IP段和业务线的对应关系是否准确比如192.168.7.0/24归哪个团队服务注册中心里有没有连续多次健康检查失败的实例它们绑定的IP是否已经过期异常流量是单IP还是整段IP整段IP往往意味着配置批量错误而不是单点攻击排查过程中保留所有ss、dig、awk的输出方便事后做根因分析这一套东西不一定每次都能直接命中根因但至少能保证你从IP维度切入时不会漏掉最关键的“链路错位”问题。尾巴上的几句实在话这次故障给我的最大感触是IP地址从来不只是机房里的一个网络术语它本质上是一条条请求在系统里走过的“足迹”。线上服务出问题的时候代码可以骗人日志可以刷屏但网络层留下来的连接关系和时间点很难造假。很多看似复杂的故障只要你愿意弯下腰去查一下连接是从哪个IP来的、又打到了哪个IP上思路就会一下子豁然开朗。我自己现在排查故障的习惯已经固定下来了任何问题进来先花五分钟把网络链路和IP关系捋清楚再决定要不要深入看代码。这个习惯帮我省下过很多个不眠夜。真希望这篇复盘能让看的人少走一点弯路至少下一次系统出问题的时候除了翻日志你也能想起先看一眼IP。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑