最常见原因是监听地址写死为127.0.0.1,导致内核丢弃外部SYN包;必须改为0.0.0.0并完整重启,同时检查worker进程是否存在、防火墙与安全组是否双层放行,以及conntrack表是否耗尽。

Workerman监听地址写死为127.0.0.1导致Connection refused
这是最常见、最隐蔽也最致命的原因:客户端连不上不是因为服务没启,而是内核压根不响应外部SYN包。只要代码里出现 new Worker('tcp://127.0.0.1:5678') 或 new Gateway('websocket://localhost:2346'),就等同于对局域网、云主机、嵌入式设备(ESP32/STM32)全部关上了门。
必须将所有监听地址显式改为 0.0.0.0,例如:
new Worker('tcp://0.0.0.0:5678')new Gateway('websocket://0.0.0.0:2346')new WebServer('http://0.0.0.0:8080')
改完不能只 reload,必须完整重启:php start.php stop && php start.php start。否则旧监听 socket 仍驻留在内核中,ss -tuln | grep :5678 依然只显示 127.0.0.1:5678。
ss -tuln 查不到监听端口,说明Worker进程根本没起来
看到 Start success 不代表一切正常——master 进程可能活着,worker 子进程却因 onWorkerStart 中未捕获异常而静默退出。此时 ps aux | grep WorkerMan 只能看到 master process,没有 worker process。
立刻检查日志末尾:
- 打开
workerman.log,搜索Fatal error、Exception、Parse error - 常见触发点:
require路径错误、扩展缺失(如pcntl未启用)、PHP 版本不兼容、配置文件语法错误 - 临时加一句
var_dump(__FILE__); exit;在onWorkerStart开头,确认是否执行到该处
防火墙和云安全组双层拦截,本地通 ≠ 外网通
在服务器上 curl -v http://127.0.0.1:5678 能通,不代表外网能连——loopback 流量完全不经过防火墙和云安全组。必须从客户端实测:telnet your-server-ip 5678 或 nc -zv your-server-ip 5678。
两道关卡都要检查:
- 系统防火墙:CentOS/Rocky 执行
sudo firewall-cmd --list-ports,缺端口就加:sudo firewall-cmd --add-port=5678/tcp --permanent && sudo firewall-cmd --reload - 云平台安全组:阿里云/腾讯云控制台 → 实例对应安全组 → 入方向规则 → 添加 TCP 端口 5678,源 IP 暂设为
0.0.0.0/0(测试用),保存后等约 10 秒生效
conntrack 表满导致新连接被内核丢弃
Workerman 日志安静、进程存活、ss -tuln 显示监听正常,但客户端反复超时或 Connection refused,且 dmesg -T | grep "table full" 刷出 nf_conntrack: table full, dropping packet ——这就是 conntrack 表耗尽的典型症状。
快速验证与处理:
- 查是否真满:
conntrack -C输出接近或等于cat /proc/sys/net/netfilter/nf_conntrack_max - 临时清无效条目(推荐):
conntrack -D --state INVALID,UNREPLIED - 调短 established 超时(长期有效):
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600 - 别忽略 TIME_WAIT 堆积:短连接密集场景下,
conntrack -L | awk '{print $4}' | sort | uniq -c | sort -nr | head -5很可能暴露出大量TIME_WAIT
真正难缠的是那种“偶尔连不上”“重启后好一阵又坏”的情况——它往往不是 Workerman 的锅,而是 conntrack 条目滞留 + 内核丢包,既不报错也不记录,只能靠 dmesg 和 conntrack -C 现场抓包。

















