ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

网络故障排查实战:从DNS解析到TCP连接的完整定位链路

网络故障排查实战:从DNS解析到TCP连接的完整定位链路 先说一个几乎所有做过线上故障处理的人都会遇到的场面业务监控大屏飘红研发群里有人喊“调不通了”紧接着就有人接一句“是不是DNS挂了”另一个人说“不对感觉是TCP连不上”。然后争论的人各自打开工具乱按一通最后靠重启大法解决问题——至于到底哪里出的问题没人说得清。我这些年被类似的“悬案”折磨过不少次后来慢慢总结出一套固定套路网络故障排查永远应该沿着“DNS解析 → 网络连通 → TCP连接 → 连接质量”这条链路一步步往下走每一层验证通过再进入下一层。这不是什么高深理论而是一条能大幅缩短排障时间、减少同事之间互相甩锅的实战路径。这篇文章我就把自己常用的这条排查链路完整梳理一遍把命令、原理、典型坑位都摆出来希望能帮你把乱七八糟的“网络不通”变成一张清晰的定位清单。适合正在自己排查服务的开发、运维、网工也适合刚入门想建立体系化排查思路的人。1. 为什么排障要按“DNS → TCP”的顺序来先画一张协议栈地图1.1 绝大多数“网络不通”的真相故障是分层的先把一个关键认知说清楚你遇到的每一个“网络不通”从来都不是一个孤立的错误而是某一层协议栈没有按预期工作。用户访问一个网站背后经过的链路大致是这样浏览器先做DNS解析拿到IP然后发起TCP连接连接建立后才是HTTP请求的发送和响应。哪怕只是“页面打不开”这五个字可能的原因就能列出一长串域名解析失败、解析到了错误IP、IP不可达、路由黑洞、防火墙拦截SYN包、连接超时、建立连接后经常断、数据包丢失严重导致请求永远发不完……如果不分层排障就像在暗室里找一只不存在的猫。你ping了一下域名发现不通立刻怀疑服务器宕机结果其实是你本地DNS缓存了解析压根没连到正确的服务器。反过来你用IP访问发现服务明明是好的但又说不清为什么域名访问偶尔超时。这些情况的本质都是没有把“哪一层出的问题”先框定住。所以我的习惯是不管用户报什么网络故障第一件事永远是把链路拆成三层来看——域名解析层、IP连通层、TCP传输层。每一层都有对应的验证工具和典型症状先定位到某一层再往细节里钻。1.2 为什么必须先从 DNS 开始而不是先抓 TCP 包有人会问既然TCP才是最基础的连接为什么不先去抓包看握手这里有个很实际的逻辑TCP连接的前提是拿到目标IP和端口而绝大多数业务场景里你要连接的服务器是用域名表示的。如果DNS解析这一关就错了——解析超时、解析到旧IP、缓存了错误结果——你后续再怎么抓TCP包都是浪费时间因为你可能在跟一个根本不对的地址较劲。另外从排查成本上看DNS解析的检查也最便宜。一条nslookup或dig命令几秒钟就能出结果而抓包分析TCP握手少说要花几分钟还要带着过滤器去判断SYN、SYN-ACK这些标志位。先做成本最低的验证再进入成本更高的环节这是排障效率的基本原则。排障顺序也对应着依赖关系TCP建立在IP之上IP建立在DNS解析出的目标地址之上。自顶向下逐层验证每过一层就排除一批可能性剩下的范围自然越来越小。等到你确认DNS没问题、IP能通再开始查TCP握手状态这时候抓包看到的东西才有意义。1.3 开工前先备好这几把“扳手”在开始讲具体排查之前我先把平时最常用的一套工具列出来。这套工具在Linux和Windows下基本都有对应版本不用装什么重型软件系统自带的能力已经够排查九成问题工具作用典型排查场景nslookup/digDNS解析查询域名解析不到、解析结果异常ping测ICMP连通性目标机器是否在线、IP是否可达traceroute/tracert路由路径追踪中间路由丢包、链路绕路telnet/nc测试端口连通性TCP端口是否对外开放curl -vHTTP访问并输出详细过程整体访问链路哪里卡住ss/netstat查看本地连接状态连接卡在SYN_SENT还是ESTABLISHEDtcpdump抓包分析定位握手失败、重传、丢包问题这套工具不用一次性全上而是按“DNS → IP → TCP”的顺序逐层启用。每验证完一层记录一下结果确认没问题再动下一层。不然工具开了一大堆信息反而是噪音。2. DNS 解析异常最隐蔽也最容易误判的坑2.1 一次域名解析要经过哪几关域名解析看似是个一步操作实际是一条完整的查询链。我在排障时习惯把它拆成四段浏览器/系统缓存 → 本机hosts文件 → 系统配置的DNS服务器 → 根服务器与权威服务器。第一段是缓存。你的浏览器、操作系统甚至路由器都会缓存DNS结果缓存有效期由域名解析结果里的TTL值决定。很多“为什么我改完域名解析了还是不生效”的问题根子就在缓存。Chrome输入chrome://net-internals/#dns可以查看并清空DNS缓存Windows下用ipconfig /flushdnsLinux下根据systemd-resolved或nscd的不同缓存机制处理。第二段是hosts文件。Windows在C:\Windows\System32\drivers\etc\hostsLinux在/etc/hosts。某些内网环境会利用hosts做域名映射如果里面写了一个过期的IP即使DNS服务器上的解析是对的实际访问还是会走hosts的旧地址。第三段才是真正意义上的DNS查询。系统把解析请求发给配置的DNS服务器这台服务器要么自己知道答案要么代表你去问根域名服务器和权威服务器。第四段就是整个递归和迭代过程通常不会出问题一旦权威服务器响应慢就会变成“解析时好时坏”的诡异现场。2.2 症状识别到底是“解析失败”还是“解析错误”很多初学者把DNS问题的症状搞混。我举几个最常见的浏览器直接报“无法找到 DNS 地址”或“找不到服务器IP地址”。这个最直接多半是当前用的DNS服务器根本没给出答案。命令行里ping example.com报unknown host说明系统层解析就失败了和浏览器报的其实是同一件事。curl访问域名报Could not resolve host同样是解析环节出了问题。更隐蔽的是“解析成功但结果不对”。比如你用nslookup能看到A记录返回IP却是别人家的旧地址或者解析到内网IP但实际服务在另一个网段。这种情况不只是“有没有解析到”还要看“解析到的对不对”。遇到“解析失败”优先查三个地方本机hosts有没有写错、当前配置的DNS服务器是否可用、这台DNS服务器是不是被运营商污染或者部分域名解析不了。遇到“解析错误”就需要对比多家DNS服务器的解析结果看看是不是只有你用的那台有问题。2.3 定位 DNS 问题三步法我一般按下面三个步骤做基本不会漏第一步用系统默认DNS解析一次看结果。nslookup example.comWindows和Linux通用dig example.comLinux更推荐输出带TTL和查询耗时。先确认默认配置下能不能解析出来。第二步换一个知名公共DNS再解析一次。比如nslookup example.com 114.114.114.114或dig 223.5.5.5 example.com看是不是换了服务器就能解析。如果默认服务器解析失败、公共DNS能成功那问题就锁定在你当前配置的那台DNS服务器上要么是它本身故障要么是它到权威链路的路径有问题。第三步对同一域名查出来的多个结果做对比。分别查询几组不同的DNS服务器把所有A记录列出来对比。如果公共DNS之间结果一致但你公司内网DNS给出的结果不一样多半是内网DNS有特殊配置或缓存过期。我遇到过不止一次内网DNS把某域名缓存在一台已经退役的服务器上导致业务偶发超时。2.4 Linux 下改 DNS 的经典坑配置总是“还原”热搜词里有一条特别真实“linux修改dns后重启网络还原”。这个问题我在Ubuntu、CentOS上都踩过根因在于不同发行版的DNS配置管理体系不一样。很多老教程让你直接编辑/etc/resolv.conf这在某些系统上确实立竿见影但一到重启网络服务或者重启机器就全没了——因为你的配置被NetworkManager或systemd-resolved覆盖了。Ubuntu 22.04这类新版系统/etc/resolv.conf通常是个软链接指向systemd-resolved生成的文件你改了等于白改。正确的做法是先确认系统用哪套网络管理机制。如果是NetworkManager用nmcli con mod改对应连接的ipv4.dns和ipv4.ignore-auto-dns如果是netplanUbuntu 22.04默认用这个就在/etc/netplan/*.yaml里修改nameservers配置然后sudo netplan apply如果只是临时测试可以用resolvectl dns命令直接临时设置。改完别忘验证resolvectl status看当前生效的DNS再用systemd-resolve --status部分版本或直接ping一个域名测试。这里还有个容易骗过自己的细节systemd-resolved默认有缓存和DNS stub就算你配置已经变了也可能要等缓存失效或手动重启systemd-resolved服务才生效。2.5 公共 DNS 怎么选延迟、可用性、内网域名的平衡很多人在选DNS服务器时只看“名气大”其实这里面的取舍挺多的。国内常见的公共DNS大概有这些DNS服务器地址特点114 DNS114.114.114.114老牌用户基数大阿里DNS223.5.5.5 / 223.6.6.6阿里云维护解析速度稳定百度DNS180.76.76.76国内节点覆盖不错电信/联通运营商DNS各省不同延迟最低但可能在部分域名上解析结果不理想1.2.4.81.2.4.8国家下一代互联网示范工程部分环境有奇效我的选择原则是办公室内网环境优先用内网DNS因为它能解析内部域名还能做内网流量的智能调度公网DNS再好也替代不了这一点。如果内网DNS抽风临时切换到公网DNS做验证是没问题的但不要长期混用否则内部服务名都解析不出来了。测DNS延迟有个简单办法dig 服务器地址 example.com看返回里的Query time。多对比几台延迟低且解析结果稳定的就是适合作默认配置的。另外如果你是在云上建了自己的DNS服务器把“转发器”指向一个稳定可靠的上游也很重要不然自己搭建的DNS会在递归查询时频频超时。3. DNS 通过之后IP 层连通性才是“中间那段看不见的路”3.1 ping 不通不代表服务一定不可用确认域名解析没问题后下一步就是验证目标IP是否可达。很多人习惯性先ping一下但对ping不通的结果过度解读反而会带偏方向。ping使用的是ICMP协议它测试的是“主机是否在线并且允许响应ICMP请求”。现实情况是很多生产环境出于安全考虑会禁掉ICMP响应比如云服务器、负载均衡器的安全组默认就不放行ping但这完全不影响TCP和HTTP服务正常访问。所以ping不通的时候不要急着下“服务器挂了”的结论先换用TCP层面的端口探测工具验证。ping真正有价值的地方在于第一能快速判断当前IP在网络里有没有路由可达第二连续ping一段时间看延迟和丢包率可以判断链路质量。比如你ping 1.1.1.1延迟只有几毫秒但ping 某云服务器延迟超过两百毫秒还伴随大量丢包那基本可以断定中间链路或路由策略有问题TCP连接自然也不会顺畅。3.2 traceroute 的用法找到“黑洞”在哪一段如果你怀疑中间链路有问题tracerouteWindows上叫tracert是下一步的核心工具。它会记录数据包从你本机经过的每一个路由节点并且打印每一跳的延迟。我遇到过一个典型场景客户端访问某个API有时候通有时候超时ping目标IP能看到少量丢包。用traceroute一查发现从本机出去的第三跳开始延迟飙升到300ms再往后几跳干脆全部* * *超时。这基本说明问题出在中间的运营商链路上而不是目标服务器本身。需要注意一条经验traceroute中间某几跳超时千万不要直接判定故障。很多运营商路由器为了性能和安全会限制ICMP的响应导致显示超时但数据包仍然正常转发。判断的标准是看最终那一跳能不能到以及整体延迟是否异常。只有最终跳也超时、或者连续多跳都丢包才说明路由真的断了。3.3 用 telnet/nc 验证“端口是否真的开放”从IP连通再往前一步就是端口可达性。这一步是最接近TCP排查的入口也是很多人容易跳过的一步。telnet 目标IP 端口是个老而实用的工具。如果端口开放你会看到Connected to或者直接进入一个黑屏光标如果端口不通会一直卡住直到超时然后报Connection refused或者Unable to connect。nc -vz 目标IP 端口在Linux下更适合脚本化检测还能一次测多个端口。这里要特别区分两种报错的含义Connection refused说明IP是通的目标机器在线但那个端口上没有服务在监听或者有防火墙主动回了RSTConnection timed out说明SYN包根本没人应答大概率是被防火墙安全组静默丢弃了或者中间链路丢包导致握手包过不去。这两种现象对应的排查方向完全不一样前者去看服务进程有没有起来后者去看安全组、iptables规则和网络链路。3.4 云上环境最容易漏的检查点安全组如果是上云的环境IP层和端口层的“隐形防火墙”一定要优先排除。云服务器的安全组规则、负载均衡器的监听规则、以及VPC内部的网络ACL任何一层Drop了流量你在服务器里面抓到包往往什么都看不到因为包根本没到达网卡。我处理过几次“服务明明在监听客户端就是连不上”的案例最后都是安全组规则只放行了一部分来源IP或者忘了放行对应端口。碰上这种情况先别急着在服务器里抓包去云控制台把安全组、网络ACL、负载均衡监听配置全过一遍确认源IP、目的端口都放行了再继续看TCP层。4. TCP 三次握手连接建不起来时到底卡在哪一步4.1 握手的本质三次状态转换TCP连接建立靠的是三次握手客户端发送SYN包服务端收到后回复SYN-ACK包客户端再回一个ACK包双方进入ESTABLISHED状态。虽然这是老生常谈但排障时必须把这三步和本机的连接状态对应起来才能真正定位问题。客户端视角发出SYN后连接状态是SYN_SENT收到服务端SYN-ACK状态会变成ESTABLISHED。如果你在客户端用ss -tn看到大量连接停留在SYN_SENT说明SYN包发出去了但一直没等到应答。原因可能是对方防火墙拦截、中间链路丢包、或者服务端的接收队列已经满了。服务端视角收到SYN后会进入SYN_RECV表示已经收到连接请求但还没完成握手。如果服务端ss -tn里堆积了大量SYN_RECV说明对方发来的SYN-ACK应答一直没收到典型原因是半连接队列溢出或者客户端回应的ACK丢了。4.2 用 curl -v 和 ss 判断“卡在握手哪一段”我最常用的组合拳是curl -v加ss -tn。curl -v会打印连接过程比如Connected to example.com port 443说明TCP已经建好了接下来卡住的话就是TLS或HTTP层的问题如果一直报Connection timed out说明还在等TCP握手这时候切到ss -tn看连接状态就非常直观。举个例子你访问某个服务超时ss -tn显示一堆SYN_SENT连接那就先把目标IP和端口拿出来在另一个网络环境比如云服务器本机试试能不能连。如果本机可以通、你这边不行多半是本地到目标之间的防火墙或路由问题如果本机也不行就是服务端的问题继续看服务端半连接队列和监听进程。4.3 半连接队列溢出一个让连接“时好时坏”的元凶在TCP握手阶段服务端维护着两个队列半连接队列存放SYN_RECV状态的连接和全连接队列存放已完成握手等待应用accept的连接。这两个队列都有上限一旦打满新的连接请求就会被直接丢弃。这就是为什么有些服务会出现“偶尔连得上、偶尔连不上”的现象连接量一上来队列满了新连接全部卡死但已有连接还在正常工作从外部看就是一部不可靠的服务。排查方法很简单ss -tn state syn-recv看半连接队列堆积数ss -lnt里看Send-Q和Recv-Q能反映全连接队列大小和当前积压。如果是Java应用报accept失败或者Nginx报504配合这两个命令基本能确认队列问题。应急措施是调大net.core.somaxconn、net.ipv4.tcp_max_syn_backlog以及应用监听接口的backlog参数治本的办法是看业务流量是否暴涨、后端处理是否过慢全连接队列堆积通常意味着应用accept速度跟不上连接建立速度。4.4 防火墙和安全组的“静默丢包”抓包才能看到真相很多防火墙配置是“静默丢弃”也就是直接扔掉你发来的SYN包不回RST也不回任何东西。客户端这边的表现就是连接一直卡在SYN_SENT直到超时。要确认这一点最有效的办法是抓包。Linux下tcpdump -nn -i eth0 tcp port 目标端口可以看到SYN包到底有没有从本机网卡发出去。如果本机已经发出SYN但一直看不到对端回任何包那问题几乎肯定在中间某个环节被丢弃了接下来就该顺着链路往上查防火墙和安全组。抓包有个容易被忽略的细节如果在云服务器上用tcpdump抓包看到SYN进来了但服务端没有回SYN-ACK这时候先看iptables规则。iptables -L -n -v能看到每条规则的匹配计数如果某个DROP规则计数在增长说明是本地防火墙干的。如果计数没增长再考虑是不是服务进程没有监听这个端口。4.5 TIME_WAIT 与“端口已在使用”经典 Java 客户端重连报错握手建立之后的资源释放阶段同样有一堆坑其中最经典的就是java tcp客户端重连时报地址已在使用。这背后是TIME_WAIT状态在作怪。TCP连接关闭时主动关闭方会进入TIME_WAIT默认等待2个MSL最大分段生存期后才会释放端口。如果应用在短时间内频繁创建、关闭连接而每次都用同一个本地端口就会在重连时报Address already in use。这个问题的根源不在于程序逻辑而在于TCP协议为了保证旧连接的迟到数据包不会干扰新连接强制让端口在TIME_WAIT期间不可复用。我见过好几个用Java或C#写TCP客户端的项目踩这个坑尤其是配合心跳重连机制时特别容易触发。缓解方式有几个一是让操作系统允许TIME_WAIT端口尽快复用net.ipv4.tcp_tw_reuse配合tcp_timestamps启用二是客户端在重连时不要固定本地端口让系统随机分配三是在设计层面控制连接频率用长连接而不是每次都新建连接。我个人更推荐后两者因为tcp_tw_reuse虽然能解决端口问题但它改变的语义需要你对内核参数有充分理解生产环境不要贸然开启。5. 连接建立成功之后握手只是开始重传和粘包才是真正的暗坑5.1 DUP ACK、重传与丢包连接“能用但很慢”的真凶TCP连接建立成功后很多人就以为万事大吉了其实TCP的可靠性机制在这一阶段才开始真正工作。握手只代表双方愿意建立连接不代表后续数据能稳定送达。最常见的两个问题是重传和重复确认DUP ACK。什么是DUP ACK简单来说接收方发现某个数据包丢了或者乱序就会针对“最后一个按序收到的数据包”重复发送ACK催促发送方赶紧补发。发送方连续收到几个DUP ACK就会触发快速重传。如果丢包严重发送方会走超时重传路线这时候TCP吞吐量会断崖式下跌。排查手段有三个层面第一ss -tin可以看每个TCP连接的重传次数和发送队列里有没有堆积第二ping目标看丢包率和延迟波动作为链路的粗参考第三tcpdump抓包统计重传包和DUP ACK的数量确定是特定链路段还是全局性问题。我在实际项目中见过不少“接口时快时慢”的案例最终抓包发现全是重传链路本身丢包率夸张TCP层的可靠机制变成了一把双刃剑——它保证了数据无损但也把延迟放大了几十倍。5.2 粘包和半包TCP 是“流”不是“消息”TCP是字节流协议它不保证你发送的每一条消息都完整、独立地到达对端。应用层发两次write底层可能合并成一个包发出去反过来一次大消息可能被拆成多个TCP段。这就是粘包和半包问题的根源。在排查这类问题时我见过太多程序员怀疑网络设备结果锅全在应用层。比如C#和Java的TCP客户端互相通信或者用Modbus TCP协议做设备通讯时如果双方没有设计明确的消息边界收方很容易把两条消息读成一条。网上的热搜词里“c# modbus tcp客户端”和“esp01s发送tcp消息手机”都是这个问题的重灾区。正确的处理方式是应用层约定消息格式常见有四种用\n换行分隔、用固定长度、用长度前缀、用特殊终结符。Modbus TCP本身就规定了MBAP头部里有长度字段但很多单片机实现时不严格按协议组包也会出现半包问题。我的经验是先抓包确认底层收到的字节流是什么样再检查解析逻辑是不是按“完整消息”来读取而不是按“一次read就是一条消息”来写代码。5.3 半开连接与 KeepAlive对方“失踪”了连接还挂着TCP还有一种很折磨人的现象连接看似还活着实际上对端已经消失了断电、断网、崩溃这就是半开连接。TCP协议本身没有内置检测对端是否活跃的机制除非你主动发包。客户端和服务端都可能在半开连接上干等。客户端等不到响应服务端这边看到的就是一堆“假连接”占用着文件描述符和内存。解决思路有两个层面应用层主动做心跳定时发探活消息超时几次就主动断开重建内核层面开启TCP KeepAlive调整net.ipv4.tcp_keepalive_time、tcp_keepalive_intvl、tcp_keepalive_probes三个参数让内核周期性地发送探测包。实际项目中我倾向于应用层心跳为主、内核KeepAlive兜底。原因很简单内核KeepAlive的探测间隔默认是2小时对于大部分业务来说太慢了而且它只能确认“对端IP栈是否活着”不能确认“对端业务进程是否正常”。真正想做健康检测还得靠自己设计的心跳协议。5.4 Nagle 算法与延迟确认小包业务的延迟杀手如果你调用的服务是小包高频交互比如物联网设备的心跳、游戏的实时状态上报那延迟不稳定多半和Nagle算法与TCP延迟确认的“打架”有关。Nagle算法会把多个小包合并发送减少网络上小包数量但代价是可能增加几十毫秒的延迟。TCP延迟确认机制则是收包后不立刻回ACK而是等一小段时间期待能和数据一起捎带回去。这两个机制叠加在一起时会出现一种经典的“确认死锁”发送方等着合并更多数据接收方等着捎带ACK两边都在等延迟就肉眼可见地恶化了。Java和C#里设置TCP_NODELAYsetTcpNoDelay(true)就是关闭Nagle算法让每个小包立即发送。但这不等于无脑开启如果你的业务本来就是大块数据传输Nagle算法反而能提升链路利用率。这个参数是典型的“场景决定论”不要照搬网上的配置。排查时可以先在抓包里看“两组小包之间的间隔是否异常”比如明明应该10ms一个包实际却等到了40ms那就要怀疑这两个机制在做怪了。5.5 MTU 与 MSS为什么小包能通大包就断还有一个比较进阶但容易被忽略的坑MTU最大传输单元导致的数据传输失败。症状很怪TCP握手没问题小包数据没问题但只要一传大文件或者大响应体连接就卡住甚至重置。原因在于网络链路中某一跳的MTU比你的包小而你又禁用了路径MTU发现导致大包被中间设备直接丢弃。排查方法是ping -M do -s 1472 目标IP测试不同大小的包能不能顺利到达。如果大包不通、小包通基本就锁定了MTU问题。解决思路包括调低本机网卡的MTU、调整TCP MSS值ip link set dev eth0 mtu 1400这种做法或者确保路径MTU发现正常工作。这个坑在跨运营商、跨国际链路时出现概率特别高国内访问海外服务时尤其常见。之前处理过一个“从国内服务器访问海外API小请求正常、大响应超时”的案例就是典型的MTU问题把接口响应体压缩到阈值以下立刻恢复正常。6. 一次完整链路排障复盘从页面打不开到 TCP 半连接队列溢出光讲理论容易散我用一个真实复盘把前面所有步骤串起来。这个案例非常有代表性某天业务方反馈官网页面“偶尔打不开”刷新几次又好了但过一阵又报超时。用户用的浏览器是Chrome报的是“无法找到DNS地址”和“连接超时”两种错误交替出现。当时第一反应当然是先调查DNS。我在用户侧机器上nslookup了一下公司域名发现默认的内网DNS服务器响应极其不稳定有时候要等两三秒才返回结果偶尔直接超时。换个公共DNS一测解析秒回结果也正确。到这一步按常规套路应该把用户机器的DNS改成公共DNS就能解决问题。但奇怪的是改完后“找不到DNS地址”确实是没了新问题浮出水面连接还是间歇性超时。这说明问题不止一层DNS只是第一个暴露的故障后续的TCP层还有问题。于是继续往下查curl -v访问官网发现卡在Trying ...之后紧接着ss -tn看到连接停留在SYN_SENT状态。SYN发出去了没人应答。这时候就到了“链路连通性”的检查环节。ping目标IP延迟正常、无丢包telnet 目标IP 443同样超时。那么问题基本锁定在服务端或中间的防火墙。登录到服务端一看ss -lnt显示监听端口的Recv-Q积压很大SYN_RECV状态的连接数量远超正常水位。再查应用进程日志发现后端业务线程在高峰期处理太慢全连接队列被占满内核只能把新进来的SYN包丢弃。结合前面DNS的问题实际上点有两个内网DNS因为配置问题导致部分机器解析走了一条慢路径后续又因为官网流量突增导致TCP半连接队列打满。最后处理方案是两层同时做先把内网DNS的转发配置和上游链路重新调整再把后端服务的accept backlog调大同时对峰值流量做扩容。这个案例很典型它说明一个“页面打不开”的现象背后可能是DNS和TCP两层问题叠加。如果你只处理了DNS那TCP的坑迟早会让故障换个面目再出现反之只调TCP参数也搞不定DNS解析的间歇性失败。这就是为什么“从DNS到TCP一步步定位”这种方式本质上是在帮你把问题切开一个接一个解决而不是靠运气撞上答案。7. 排障命令速查与沉淀下来的几条经验7.1 命令速查表按场景直接找工具把前面涉及到的常用命令整理成一张速查表排查时对照着用就行。排查目标命令关键观察点域名解析是否正常nslookup example.com/dig example.com返回的A记录、查询耗时指定DNS服务器解析nslookup example.com 114.114.114.114对比结果是否一致清空系统DNS缓存Windows:ipconfig /flushdns执行后提示“已成功刷新DNS解析缓存”查看hosts文件Windows:C:\Windows\System32\drivers\etc\hosts是否有过期的域名映射IP连通性ping -c 5 目标IP丢包率、延迟波动路由路径traceroute 目标IP中间跳延迟是否异常端口开放检查telnet 目标IP 端口/nc -vz 目标IP 端口Connection refused还是超时查看TCP连接状态ss -tn/ss -tn state syn-sentSYN_SENT堆积、ESTABLISHED数量查看监听队列ss -lntRecv-Q和Send-Q是否积压抓包分析tcpdump -nn -i eth0 tcp port 443SYN、SYN-ACK、重传包查看TCP重传ss -tinretrans计数是否持续增长防火墙规则计数iptables -L -n -v被DROP规则的计数是否增长7.2 这些年排障我总结的几条“心法”最后分享几条我自己沉淀下来的习惯不一定写在什么教科书里但实战中非常有用。第一一次只改一个变量。很多故障排查到最后发现问题是过去两三个小时里别人顺手改过配置导致的。你如果同时改了三处配置烧香式地重启服务问题就算消失了你也不知道是哪个改动起的作用。规范操作是先记录当前状态做一次改动就验证一次验证通过再动下一个。第二抓包要趁早不要等“实在没办法了再抓”。抓包不是最后手段而是最有力的证据。tcpdump在问题发生时打开哪怕只看几十秒都能帮你把“理论上的问题”变成“证据确凿的问题”。我经常看到有人花一两个小时猜防火墙、猜路由最后抓包三分钟就定位了。第三现象和时间线一定要记录。什么时候开始报错、当时有没有发版、有没有改配置、是不是周期性出现这些信息比任何命令都值钱。很多神秘故障的答案就藏在“报错时间点”和“变更时间点”的重合里。网络故障排查这件事本质上拼的是耐心和条理。技术命令背得再多没有一套清晰的定位思路遇到复杂场景还是容易原地打转。按照“DNS → IP连通 → TCP连接 → 连接质量”这条链路一层层验证下去大多数看起来玄乎的网络问题最后都会落在某个具体的可修复点上。
返回列表