三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

网络排障必备:从ping到tcpdump,程序员必须掌握的7个核心命令

网络排障必备:从ping到tcpdump,程序员必须掌握的7个核心命令

1. 从“ping不通”说起:为什么网络命令是程序员的必备技能

前几天,一个刚入行的同事在部署测试环境时遇到了一个经典问题:本地开发的微服务死活连不上测试数据库。他对着屏幕上的“Connection refused”错误码,第一反应是去翻代码、查配置,折腾了半个多小时。我过去看了一眼,让他先别急着改代码,在终端里敲了两行命令:ping了一下数据库服务器的IP,发现能通;再用telnet试了一下数据库的端口,果然连不上。问题瞬间清晰了——不是代码问题,是测试环境的数据库服务根本没起来,或者防火墙规则没放行。这件事让我再次意识到,无论你是前端、后端还是运维,掌握几个基础网络命令,就像电工会用万用表测电路一样,是定位问题的“第一性原理”工具,能帮你快速区分问题是出在“网络层”、“服务层”还是“应用层”,避免在错误的方向上浪费大量时间。

很多人觉得网络命令是运维的专属领域,或者认为在云原生和容器化时代,这些“古老”的命令已经过时了。恰恰相反,越是抽象和复杂的架构(比如K8s集群、Service Mesh),底层网络的连通性问题就越发关键和隐蔽。当你的Pod无法通信、Service无法访问时,最终还是要回到主机层面,用这些最基础的工具去探查网络路径、检查端口监听、分析数据包。它们是你穿越复杂架构迷雾,直指问题本质的“探针”。这篇文章,我就结合自己十多年踩坑填坑的经验,把几个最常用、最高频的网络命令掰开揉碎了讲清楚,不止告诉你命令怎么敲,更重点分享每个命令在什么场景下用、输出结果怎么看、以及那些容易让人掉进去的“坑”。

2. 连通性探测基石:ping 与 telnet/nc 的职责边界与深度解读

当遇到“连不上”的问题时,我们的排查应该有清晰的层次。首先确认目标机器是否“活着”,其次确认目标服务是否“醒着”。pingtelnet(或nc)就是分别对应这两个层次的核心工具。

2.1 ping:它真的只是“看看人在不在”吗?

ping命令利用 ICMP(Internet Control Message Protocol)协议的回显请求和回显应答报文来检测网络层的连通性。它的基本用法很简单:ping <目标IP或域名>

关键输出解读与实战场景:

  1. 序列号(icmp_seq)与往返时间(time):这不仅告诉你通了,还能看出网络质量。如果time值波动巨大(例如从 1ms 跳到 200ms),可能链路上存在拥塞或抖动。如果某个icmp_seq的回复丢失(显示 “Request timeout”),说明存在偶发的包丢失,这在音视频或实时通信场景下是致命问题。

  2. TTL(Time To Live)值:这个值非常有用。TTL是IP报文的一个字段,每经过一个路由器(一跳)就减1。从回复报文中的TTL初始值,可以反推操作系统的类型或经过的跳数。常见的初始TTL值:Linux/Unix 通常是 64, Windows 通常是 128。如果你ping一个地址返回的 TTL 是 56,那么它可能是一个初始TTL为64的Linux服务器,数据包在途中经过了64-56=8个路由器。这在判断网络路径复杂度时是个小技巧。

  3. “未知的名称或服务” vs “目标主机不可达”:这是两个完全不同的错误。

    • ping: unknown host:这发生在第一步——DNS解析失败。说明你的系统无法将你输入的域名解析为IP地址。你需要检查/etc/hosts文件或DNS配置(/etc/resolv.conf)。
    • From ... Destination Host Unreachable:这通常来自你的默认网关或沿途的路由器,它告诉你“我不知道怎么去这个目标网络”。这说明你的主机路由表可能有问题,或者网关配置错误。

注意:很多云服务器或生产环境的安全组/防火墙默认会禁止ICMP协议(即禁ping)。所以,ping不通绝不等于网络不通或机器宕机!它只意味着“ICMP回显请求被拦截了”。这是ping命令最大的局限性,也是新手最容易误解的地方。

2.2 telnet 与 nc:服务层可达性的“敲门砖”

ping通(或即使不通,但你知道是禁ping策略),下一步就是检查具体的服务端口是否开放并可建立TCP连接。这里telnetnc(netcat) 是更好的工具。

  • telnet <IP> <端口>:经典工具,几乎所有系统都预装。如果连接成功,你会看到一个空白屏幕或显示服务标识(如连接MySQL会看到版本信息)。如果失败,会有明确的错误提示。
  • nc -zv <IP> <端口>nc更强大,-z参数表示扫描(不发送数据),-v表示详细输出。它比telnet更简洁,适合脚本化批量检查。

连接结果分析:

  • 连接成功:说明TCP三层握手完成,目标IP的指定端口上有进程在监听并接受了连接。至此,可以确定网络通路和端口监听是正常的,问题很可能上移到应用层协议(例如HTTP返回500错误)。
  • Connection refused:这是最常见的错误之一。它意味着你成功到达了目标机器,并且该机器上的TCP/IP协议栈收到了你的连接请求,但是该端口上没有进程在监听。可能的原因:服务没启动、服务崩溃、服务监听了其他端口。
  • Connection timed out:连接超时。这通常意味着你的SYN包没有收到任何回应。可能的原因:中间有防火墙丢弃了你的包(不同于拒绝,丢弃是静默的);目标机器确实宕机;或者路由不可达。
  • No route to host:网络层路由问题,你的主机根本不知道如何发送数据包到那个网络。

实操心得:我习惯用nc替代telnet做端口检查,因为它的输出更干净,且-z模式快速无交互。对于需要检查大量端口(例如检查一个服务器开放了哪些服务)的情况,可以写一个简单的循环脚本:for port in {80, 443, 3306, 8080}; do nc -zv your_server $port 2>&1; done。另外,在容器内检查宿主机端口或跨节点检查时,要特别注意IP地址是否正确(容器内通常不能直接用127.0.0.1访问宿主机服务)。

3. 本地视角:用 netstat 和 ss 看清你的“家门”

知道了外面能连进来,更要清楚自己家里开了哪些“门”(端口)在对外服务。netstat是传统工具,而ss(socket statistics) 是其更现代、更快速的替代品,来自iproute2软件包,在处理大量连接时优势明显。

3.1 netstat:经典但依然有效

常用组合命令:netstat -tunlp

  • -t:显示TCP连接
  • -u:显示UDP连接
  • -n:以数字形式显示地址和端口(禁用反向域名解析,更快更清晰)
  • -l:仅显示监听(LISTEN)状态的套接字
  • -p:显示占用该套接字的进程ID和程序名(需要sudo权限)

解读关键列:

  • Proto: 协议(tcp/udp)。
  • Local Address: 本地地址和端口。0.0.0.0:80表示监听所有网卡的80端口;127.0.0.1:3306表示只监听本机回环地址,外部无法访问。
  • Foreign Address: 远程地址和端口,对于监听套接字,通常是0.0.0.0:*
  • State: 状态。LISTEN(监听)、ESTABLISHED(已建立连接)、TIME_WAIT(等待关闭)等。
  • PID/Program name: 进程信息。

3.2 ss:新时代的利器,必须掌握

ss命令语法与netstat类似,但更强大。常用:ss -tunlp参数含义与netstat一致。它的输出速度远超netstat,尤其是在连接数上万的时候。

高级过滤技巧(这是ss的精华):ss支持丰富的过滤表达式,能直接定位问题。

  • 查看所有已建立的到特定IP的连接:ss -tun dst <目标IP>
  • 查看本地哪个进程在监听8080端口:ss -tunlp sport = :8080
  • 查看所有处于TIME-WAIT状态的连接(常用于排查连接未正常关闭的问题):ss -tun state time-wait

踩坑记录:曾经遇到一个服务器CPU飙升,用top看到某个Java进程占用率高。用ss -tunp | grep java进程PID发现该进程建立了上千个ESTABLISHED的数据库连接,远超连接池配置。顺藤摸瓜,发现是应用代码中在循环内错误地创建了连接而未关闭。ss快速地将网络现象与具体进程关联,极大缩短了排查时间。另一个常见坑是看到TIME-WAIT状态连接过多,这通常是高并发短连接服务的正常现象,但如果系统参数net.ipv4.tcp_tw_reusenet.ipv4.tcp_tw_recycle(后者在高版本内核中已废弃)配置不当,可能会影响新连接的建立。

4. 路由追踪与网络路径诊断:traceroute/mtr 与 dig/nslookup

当网络连通性问题发生在路径中间,而非两端时,我们需要工具来描绘数据包的旅行地图。

4.1 traceroute 与 mtr:发现路径上的“堵点”

  • traceroute <目标>:原理是发送TTL递增的UDP包或ICMP包。当TTL=1时,第一个路由器回复“超时”消息,暴露自己IP;TTL=2时,到达第二个路由器…以此类推,直到到达目标。
  • mtr <目标>traceroute的增强版,像tracerouteping的结合体。它会持续向路径上的每一跳发送数据包,并实时统计丢包率和延迟,是诊断网络间歇性问题的神器

解读mtr报告:运行mtr 8.8.8.8,你会看到一个动态更新的表格。关键列:

  • Loss%:该跳的丢包率。重点看最后一跳的丢包率。中间某跳有丢包(比如30%),但后续跳和最终目标丢包率为0,那说明中间那跳的路由器可能只是限制了ICMP/UDP探测包的回复速率,并非真实业务流量丢包。这是一个经典误区!
  • Avg/Best/Worst:平均、最佳、最差延迟。如果某跳之后延迟显著增加,说明该节点或之后的链路可能是瓶颈。
  • Last:最近一次探测的延迟。

实战场景:用户反馈访问你的海外站点慢。你在服务器上ping用户IP可能延迟正常。但让用户运行mtr 你的服务器IP,可能会发现数据包在进入某个运营商网络(如某地城域网)后延迟暴增或丢包严重。这份报告就是你和用户运营商沟通最有力的证据。

4.2 dig 与 nslookup:域名解析的“显微镜”

所有网络连接的第一步往往是域名解析。解析出问题,一切白搭。nslookup是交互式工具,而dig(Domain Information Groper) 功能更强大,输出更详细,是专业人士的首选。

dig核心用法:

  • dig <域名>:查询A记录(IPv4地址)。
  • dig <域名> MX:查询邮件交换记录。
  • dig <域名> NS:查询权威名称服务器。
  • dig <域名> TXT:查询TXT记录(常用于验证域名所有权或配置SPF等)。
  • dig @<DNS服务器> <域名>:指定DNS服务器进行查询,用于对比验证。例如dig @8.8.8.8 example.comdig @114.114.114.114 example.com结果是否一致。

解读dig输出:重点关注ANSWER SECTION,它给出了最终的解析结果。Query time表示本次查询耗时。SERVER行显示了你实际使用的DNS服务器。

排查DNS问题的经典流程:

  1. dig <域名>:查看本地配置的DNS服务器返回的结果。
  2. dig @8.8.8.8 <域名>:用公共DNS验证,如果结果不同,可能是本地DNS缓存了错误记录或配置有问题。
  3. dig <域名> NS然后dig @<权威NS> <域名>:获取该域名的权威NS,并直接向权威NS查询,这能绕过所有缓存,得到最准确、最新的记录。如果权威NS的记录是正确的,而你的本地查询错误,问题就出在递归解析链路上(如本地DNS服务器、ISP的DNS)。

注意:修改DNS记录(如A记录、CNAME)后,由于全球DNS缓存的存在(TTL控制),变更不会立即生效。dig命令结果中的TTL值表示该记录还能被缓存多久(秒)。在变更期间,用dig指定不同DNS服务器查询,是验证变更是否已同步到各节点的最佳方法。

5. 全能抓包分析:tcpdump 入门与核心过滤技巧

如果说前面的命令是“听诊器”和“X光”,那么tcpdump就是“手术刀”和“显微镜”,它能让你看到线路上流动的每一个比特。对于解决复杂的协议交互问题、性能问题、安全问题,tcpdump不可或缺。

5.1 基础抓包与保存

  • 监听指定网卡sudo tcpdump -i eth0。如果不指定-i,默认监听第一个非回环网卡。
  • 监听特定主机sudo tcpdump host 192.168.1.100(抓取与192.168.1.100相关的所有进出流量)。
  • 监听特定端口sudo tcpdump port 80
  • 组合过滤sudo tcpdump -i eth0 host 10.0.0.1 and port 443
  • 保存到文件sudo tcpdump -i eth0 -w capture.pcap-w选项将原始数据包保存为pcap文件,方便用Wireshark等图形化工具进行更深入的分析。
  • 读取pcap文件tcpdump -r capture.pcap

5.2 核心过滤表达式(BPF语法)

这是tcpdump的灵魂,让你从海量数据中精准捕获目标。

  • 方向src(源),dst(目的)。例如src host 10.0.0.1
  • 协议tcp,udp,icmp,arp。例如tcp port 22
  • 逻辑运算符and(与),or(或),not(非)。例如host 10.0.0.1 and not port 22(抓取与10.0.0.1相关,但非SSH的流量)。
  • 更细粒度的TCP标志过滤(非常实用):
    • tcp[tcpflags] & (tcp-syn) != 0:捕获所有SYN包(连接建立请求)。
    • tcp[tcpflags] & (tcp-ack) != 0:捕获所有ACK包。
    • ‘tcp[13] & 2 != 0’:这是另一种写法,13是TCP头中标志位的偏移量,2是SYN位。这个技巧可以抓取特定标志组合的包,例如抓取tcp[13] == 0x12可以抓取SYN-ACK包。

5.3 实战案例:分析一次失败的HTTP请求

假设你的应用调用一个内部API超时。

  1. 在客户端抓包sudo tcpdump -i any host <API服务器IP> and port <API端口> -w client.pcap-i any表示监听所有网卡。
  2. 复现问题。
  3. 停止抓包,用tcpdump -r client.pcap -nn查看。-nn禁止端口和地址解析,让输出更清晰。
  4. 分析:你可以清晰地看到TCP三次握手是否成功(SYN -> SYN-ACK -> ACK)。如果只有客户端发出的SYN,没有收到SYN-ACK,那就是网络或防火墙问题。如果握手成功,可以看到后续的HTTP请求(GET/POST报文)和响应。如果客户端发送了请求后,一直没收到响应,可能是服务端处理超时或网络中断。如果看到了TCPRST标志,表示连接被强制重置。

高级技巧与避坑:

  • 限制抓包大小-s参数可以指定抓取每个数据包的前多少字节。例如-s 96抓取前96字节(通常包含完整的IP头、TCP头和一部分应用层数据),对于基础分析足够,且能减少文件大小和性能开销。
  • 注意性能:在生产环境高流量网卡上抓包,不加过滤可能会瞬间产生巨大流量导致丢包(tcpdump输出会显示packets dropped by kernel)。务必使用精确的过滤表达式,只抓问题相关的流量。
  • 读懂输出:典型的TCP包输出IP client.ip.port > server.ip.port: Flags [S], seq ...[S]是SYN,[.]是ACK,[P.]是PSH+ACK(通常携带应用数据),[F.]是FIN+ACK(连接关闭)。

掌握tcpdump,你就拥有了在网络上“慢放”和“回看”任何通信过程的能力。从简单的连接问题到复杂的协议交互Bug,它都能提供无可辩驳的一手证据。刚开始看十六进制和协议字段会头疼,但结合Wireshark的图形化分析,多练几次就能找到感觉。这是从“普通开发者”迈向“能解决复杂问题开发者”的关键技能之一。

← 返回列表