查端口用lsof -i :端口号,可直接显示占用进程名、pid和用户;若未安装需apt install lsof或apk add lsof;注意ipv6兼容性,netstat需root权限才显pid。

查端口谁在用:Linux/macOS 用 lsof -i :<port></port> 最直接
报错里写的端口号(比如 8282 或 1236)就是你要查的目标。直接运行 lsof -i :8282,它会立刻返回占用该端口的进程名、PID 和用户。如果提示 command not found,说明系统没装 lsof —— Alpine 等精简镜像默认不带,得先 apk add lsof;Ubuntu/Debian 则用 apt install lsof。
注意别漏掉 IPv6 地址变体:lsof -i :8282 能同时覆盖 0.0.0.0:8282 和 :::8282;而 netstat -tulnp | grep :8282 需要 root 权限才显示 PID,否则只能看到端口状态,找不到是谁。
Workerman 自己占着自己:多进程 + 残留子进程是真凶
Workerman 默认启动多个 worker 进程($worker->count = 4),但 Linux 下所有子进程都尝试 bind 同一个端口。旧进程若没干净退出(比如 kill -9 主进程、断电、OOM),它们还在后台跑着,新启动就会撞上“Address already in use”。
- 先用
ps aux | grep start.php或ps aux | grep YourAppPath扫一遍残留的 PHP 进程 - 别只 kill 主进程 PID,要干掉整组:
kill -9 $(pgrep -f "YourAppPath/start.php") - 开发环境可加临时清理逻辑(生产禁用):
exec("killall -u $(whoami) php 2>/dev/null");放在start.php开头 - 检查
pidFile是否失效:老版本 Workerman 把 pid 存在/tmp/,系统自动清空后restart就找不到主进程,退化成“假重启”,旧 worker 仍在
配置改了但 register 没同步:GatewayWorker 常见双坑
GatewayWorker 架构里有两层监听:业务 worker(比如 new Worker("websocket://0.0.0.0:7272"))和 register worker(默认 127.0.0.1:1236)。你改了业务端口,但 register 还卡在旧地址,或者客户端连的还是旧 register 地址,都会导致启动失败或连接不上。
确认 register 端口是否匹配:
- 启动时显式指定:
php start.php start -d --register-addr=127.0.0.1:1237 - 检查客户端代码里
registerAddress配置项是否指向新端口 - Gateway 构造参数里的
$gateway = new Gateway("websocket://0.0.0.0:7272")和 register 地址是解耦的,必须两边手动对齐
快速绕过但别依赖:$worker->reusePort = true
Linux 内核 3.9+ 支持 SO_REUSEPORT,设为 true 后,多个 worker 进程可以安全地 bind 同一端口,避免因 fork 顺序引发的冲突。但这只是缓解手段,不是根治方案。
启用方式很简单:
$worker = new Worker("tcp://0.0.0.0:8282");
$worker->reusePort = true;
但它不解决以下问题:残留进程占端口、register 配置错、防火墙拦截、或端口本身被其他服务(如 Nginx、MySQL)占用。排查仍需从 lsof 或 netstat 开始——毕竟 reusePort 只让 Workerman 内部“和平共处”,挡不住外部进程抢地盘。











