4. Linux 端口排查:四把利刃在手
端口排查这事儿,说白了就是「谁在哪个口上蹲着」。QUIC 跑在 UDP 上,跟 TCP 的排查思路不太一样。我这些年踩过的坑,十有八九都是端口没查清楚。今天把这四把刀磨利了,以后遇到端口问题,你心里就有底了。
核心思路:先看端口有没有在监听,再看哪个进程占着,最后确认能不能连上。QUIC 用的是 UDP,别光盯着 TCP 看。
4.1 netstat:老牌工具,依然能打
netstat 是我刚入行时用的第一个网络排查工具。虽然现在有了 ss,但很多老系统上还得靠它。
常用参数组合:
# 查看所有 UDP 监听端口(QUIC 重点关注)
netstat -uan
# 查看所有 TCP 监听端口
netstat -tan
# 显示进程信息(sudo 才能看到别人的进程)
sudo netstat -tunlp
# 只看 QUIC 常用的 443 端口
sudo netstat -unlp | grep 443
参数说明:
| 参数 | 含义 | 我的习惯 |
|---|---|---|
| -u | 显示 UDP | 查 QUIC 必加 |
| -t | 显示 TCP | 顺便看看有没有冲突 |
| -n | 不解析域名 | 加这个快很多 |
| -l | 只显示监听状态 | 排查服务端够用了 |
| -p | 显示进程 PID/名称 | 定位问题必备 |
我的经验:有一次线上 QUIC 服务连不上,我 netstat -tunlp 一看,443 端口确实在监听。但仔细一看,是 TCP 的 443,UDP 的 443 根本没起来。嗯,QUIC 用的是 UDP,这个坑我替你们踩过了。
4.2 ss:现代 Linux 的标配
ss 是 netstat 的替代品,性能更好,信息更全。我个人习惯,新系统上直接用 ss。
常用命令:
# 查看所有 UDP socket
ss -uan
# 查看所有 TCP socket
ss -tan
# 显示进程信息
sudo ss -tunlp
# 只看特定端口
sudo ss -unlp 'sport = :443'
# 查看 socket 详细信息(缓冲区大小等)
sudo ss -unlp -o
ss 和 netstat 的对比:
| 对比项 | netstat | ss |
|---|---|---|
| 性能 | 读取 /proc 文件系统,慢 | 直接读取内核信息,快 |
| 信息量 | 基础信息 | 更详细,支持过滤 |
| UDP 支持 | 支持 | 支持,且更准确 |
| 适用场景 | 老系统、临时排查 | 日常排查、性能调优 |
注意:ss 的输出里,UDP 的 State 列通常是 UNCONN(未连接),这是正常的。UDP 是无连接的,不像 TCP 有 LISTEN、ESTAB 这些状态。我第一次看到 UNCONN 时还以为服务没起来,白忙活半天。
4.3 lsof:谁动了我的端口
lsof 是「List Open Files」的缩写。在 Linux 里,一切皆文件,socket 也是文件。lsof 能告诉你哪个进程打开了哪个端口。
实战命令:
# 查看 443 端口被谁占着
sudo lsof -i :443
# 只看 UDP 的 443
sudo lsof -i UDP:443
# 查看某个进程打开了哪些端口
sudo lsof -p 12345
# 查看所有 UDP 监听端口
sudo lsof -i UDP -s UDP:LISTEN
输出解读:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
quic-server 12345 root 3u IPv4 123456 0t0 UDP *:443
- COMMAND:进程名,一眼看出是谁
- PID:进程 ID,杀进程时用
- FD:文件描述符,3u 表示第 3 个文件描述符,u 表示可读写
- TYPE:IPv4 或 IPv6
- NAME:UDP *:443,表示监听所有网卡的 443 端口
避坑指南:我曾经遇到一个情况,lsof -i :443 什么都没输出,但服务就是连不上。后来发现 QUIC 服务监听的是 UDP 443,而 lsof 默认只看 TCP。加上 UDP 参数就好了。记住:QUIC 是 UDP,查的时候别漏了。
4.4 /proc 文件系统:底层真相
/proc 是 Linux 内核暴露给用户的信息窗口。虽然平时用 netstat、ss 就够了,但有些极端情况,比如工具坏了、权限不够,就得直接翻 /proc。
核心文件:
# 查看所有 TCP/UDP socket 信息
cat /proc/net/tcp
cat /proc/net/udp
# 查看某个进程的 socket 信息
ls -la /proc/12345/fd/ | grep socket
# 查看 socket 的详细状态
cat /proc/net/udp | grep 443
/proc/net/udp 输出解读:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:01BB 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 123456 1 0000000000000000 100 0 0 10 0
- local_address:本地地址和端口,00000000:01BB 表示 0.0.0.0:443(01BB 是 443 的十六进制)
- rem_address:远程地址,全 0 表示监听状态
- st:状态,07 表示 UDP 监听(UNCONN)
- uid:运行该 socket 的用户 ID
- inode:inode 号,可以用来关联进程
实用技巧:用 inode 号反查进程:
# 找到 inode 为 123456 的进程
find /proc -name "fd" -exec ls -l {} \; 2>/dev/null | grep "socket:\[123456\]"
这招在工具全挂的时候特别好用。我有一回在生产环境上,ss 和 lsof 都报错,就是靠这招找到的罪魁祸首。
4.5 知识体系总览
下面这张图,把四把利刃的关系和适用场景串起来了。建议你保存下来,排查问题时对照着看。
4.6 实战排查流程
遇到 QUIC 端口问题,我一般按这个顺序来:
- 先用 ss 扫一眼:
sudo ss -unlp | grep 443,看端口有没有在监听 - 再用 lsof 确认进程:
sudo lsof -i UDP:443,看是哪个程序占着 - 如果 ss 和 lsof 都挂了:直接翻
/proc/net/udp,用 inode 反查 - 最后用 netstat 兜底:老系统上可能只有 netstat
重要提醒:QUIC 用的是 UDP,不是 TCP。很多新手查端口时只查 TCP,结果服务明明在跑,却以为没起来。我见过不止一次这种 case。记住:查 QUIC,加 -u 参数。
这四把刀,你平时用 ss 和 lsof 就够了。但 /proc 和 netstat 也得会,万一哪天工具出问题,它们能救命。嗯,今天就到这儿,下节课我们讲怎么抓包分析 QUIC 流量。