科技 · 实用指南
Linux 报“Address already in use”?终止进程或重试前先证明套接字归属
端口号本身不是事故。先记录协议、地址族、地址、端口或路径与网络命名空间,证明哪个进程或 socket 单元拥有这组精确元组,再只修复一个归属边界并重复启动。

端口号本身不是事故。先记录协议、地址族、地址、端口或路径与网络命名空间,证明哪个进程或 socket 单元拥有这组精确元组,再只修复一个归属边界并重复启动。
EADDRINUSE 表示所请求地址发生 bind 冲突,不等同于权限不足或本机地址不存在。 TCP 与 UDP 分离;IPv4 与 IPv6 通配监听仍可能因配置重叠。
1. 冻结精确 bind 元组与失败系统调用
记录准确错误与 bind 参数:TCP、UDP 或 UNIX 套接字,IPv4 或 IPv6,具体或通配地址,端口或路径,以及进程、容器、服务单元和网络命名空间。改动前先区分 EADDRINUSE、EADDRNOTAVAIL 与 EACCES。
保留启动命令、配置、单元文件和时间线。在确认请求元组与归属边界前,不要批量终止某种运行时、删除 UNIX 套接字路径或启用复用选项。
2. 在正确命名空间检查持有者
在发起 bind 的命名空间内检查套接字。使用数值化的监听和已绑定未监听视图,在权限允许时记录本地元组、状态、UID、套接字 inode、PID 与命令,并与服务和容器启动时间线对照。
同时检查 socket 单元与服务进程。使用套接字激活时,systemd 合法持有监听并交给守护进程;如果服务忽略继承描述符再次 bind,即使相关进程看似正常也会冲突。
3. 区分通配、激活与交接冲突
判断具体地址是否撞上通配监听、IPv6 通配是否同时覆盖 IPv4、涉及 TCP 还是 UDP,以及端点是 UNIX 路径还是抽象套接字。不要把相同数字的所有出现都当成同一个套接字。
如果工具先向内核索要空闲端口、关闭临时套接字、稍后才真正 bind,其他进程可能在检查与使用之间抢占。应原子保留交接或在真实 bind 处有限重试,而不是反复预扫描。
4. 只修复一个已证明的归属边界
非预期持有者应通过真正的监督器停止,并确认套接字关闭后再启动。预期持有者若是 socket 单元,服务应消费继承描述符。两个配置监听重叠时,只保留一个权威地址与地址族。
SO_REUSEADDR 只用于文档允许的重启语义。SO_REUSEPORT 只在所有监听者都在 bind 前主动参与且同 UID 边界可接受时使用。不要用复用选项掩盖未知持有者。
5. 重复启动并证明归属稳定
在预发布或受控维护窗,从干净状态启动,证明精确元组由预期 PID 或单元在预期命名空间拥有,并验证健康端点或协议响应,再由真实监督器停止和重启。
执行快速重启和一次并发启动。验收要求一个明确持有者或一个设计好的复用组、无间歇 bind 失败、停止后无孤儿监听且可回滚。若竞态复现,保留时间线并修复交接,而不是盲目增加重试。
