hyperf 启动报“address already in use”本质是端口(如9501)被残留进程占用,需用sudo ss -tuln | grep ':9501'确认占用,再通过lsof或pkill精准清理php/hyperf子进程,优先kill后降级kill -9,docker场景需同步清理容器。

Hyperf 启动报“Address already in use”或类似端口冲突错误,本质是目标端口(如 9501)正被其他进程监听。排查关键在于快速定位、精准清理,避免误杀系统服务。
确认端口是否真被占用
先验证问题是否存在,排除配置错误或端口写错的情况:
- 运行 sudo ss -tuln | grep ':9501'(推荐,比 netstat 更快更轻量)
- 若无输出,说明端口空闲,问题可能出在 Hyperf 配置(如
server.port写错)、SELinux/firewalld 限制,或监听地址设为127.0.0.1而你从外网访问 - 若有输出,看最后一列的
users:(("xxx",pid=1234,fd=...))—— 这就是线索
查出是谁在占着 9501
Hyperf 常见的“幽灵占用”不是常规守护进程,而是残留的 Swoole 子进程或 nohup 启动未清理的 php 进程:
- 用 sudo lsof -i :9501 查进程名和 PID;注意看 COMMAND 列是否为
php或hyperf.php - 若
ps aux | grep php看不到,但lsof能查到,大概率是子进程已脱离父进程、PPID 变成 1(init/systemd),成了孤儿进程 - 特别检查 Docker:运行 docker ps -a | grep 9501,旧容器即使已退出,也可能因端口映射残留绑定(尤其用
-p 9501:9501启动过)
安全终止占用进程
不建议一上来就 kill -9,优先尝试优雅关闭:
- 如果查到 PID 是 1234,先试 kill 1234(发 SIGTERM,让进程自行释放资源)
- 等 3–5 秒后,再用
ss -tuln | grep 9501检查是否释放;若仍在,再执行 kill -9 1234 - 批量清理所有 php 监听 9501 的进程:sudo pkill -f 'bin/hyperf.php start'(注意加
-f匹配完整命令行) - Docker 场景:直接清理相关容器 docker rm -f $(docker ps -aq --filter "expose=9501")
启动前自动防占用(一劳永逸)
把检测+清理做成一行脚本,集成进部署流程:
- 例如在启动前加一句:sudo lsof -ti:9501 | xargs -r kill -9 && php bin/hyperf.php start
-
-r表示输入为空时不执行 kill,避免报错;-ti只输出 PID,干净利落 - 生产环境建议搭配 systemd service,用
Restart=on-failure和ExecStartPre=...自动清理











