关于单主机套接字数量耗尽引发的错误追踪及TCP源端口耗尽相关问题咨询
单主机套接字数量耗尽引发的错误追踪及TCP源端口耗尽相关问题咨询
嘿,这个问题问得很到位——我刚好对TCP源端口耗尽的场景和追踪方法比较熟悉,给你详细拆解下:
内核返回的错误码
当客户端主机因为没有可用源端口导致TCP连接失败时,Linux内核返回的错误码是EADDRNOTAVAIL(对应errno数值99)。
简单说下背景:TCP客户端发起连接时,需要从系统配置的源端口范围里选一个未被占用的端口。默认情况下,Linux的源端口范围一般是32768到60999(可以通过/proc/sys/net/ipv4/ip_local_port_range查看或修改),当这个范围内的所有端口都被已建立的连接占用时,内核没法分配新的源端口,就会抛出这个错误。
注意:不同操作系统的错误码可能有细微差异,比如Windows下对应的是WSAEADDRNOTAVAIL(错误码10049),但主流Linux环境下都是
EADDRNOTAVAIL。
用于计数的bpftrace脚本
这里给你一个轻量的bpftrace脚本,专门用来统计因源端口耗尽导致的连接失败次数,还能按进程维度统计:
#!/usr/bin/bpftrace // 追踪connect系统调用的退出事件,捕获失败情况 tracepoint:syscalls:sys_exit_connect { // 判断返回值是否为-EADDRNOTAVAIL(内核用负的errno表示系统调用失败) if (args->ret == -99) { // 按进程名累计失败次数 @fail_count[comm] = count(); // 可选:实时打印触发失败的进程信息,方便排查 printf("[%s] PID %d: Connect failed due to source port exhaustion (EADDRNOTAVAIL)\n", comm, pid); } } // 当脚本退出时,打印汇总统计结果 END { printf("\n=== Source Port Exhaustion Connect Failure Summary ===\n"); print(@fail_count); }
使用方法:
- 把上面的代码保存为
port_exhaustion_tracker.bt - 给脚本添加执行权限:
chmod +x port_exhaustion_tracker.bt - 用root权限运行:
sudo ./port_exhaustion_tracker.bt
运行后,脚本会实时输出触发源端口耗尽的进程信息,当你按下Ctrl+C退出时,会打印各个进程的失败次数汇总。这个脚本开销极低,不会影响系统性能,适合在生产环境临时排查问题。
备注:内容来源于stack exchange,提问作者eof
相关产品推荐
相关产品推荐

