“connection timed out”本质是tcp握手失败,主因是监听地址错误(如127.0.0.1)、云安全组/防火墙未放行、内核参数未调优(somaxconn、ip_local_port_range、tcp_tw_reuse)及未启用reuseport。

Workerman服务在高并发或嵌入式设备连接场景下频繁报“Connection timed out”,说明客户端根本没完成TCP三次握手——SYN包发出去后,服务端连SYN-ACK都没回,不是业务逻辑卡住,而是连接建立阶段就断在了网络链路或内核层面。
确认监听地址是否对外可见
第一步:打开start.php,找到Worker实例化代码,检查协议和地址是否写成tcp://127.0.0.1:5678或websocket://localhost:2346;这种写法只响应本机回环流量,外部设备发包到服务器真实IP时,Linux内核直接丢弃。
第二步:必须改成tcp://0.0.0.0:5678或websocket://0.0.0.0:2346,确保监听所有网卡接口。
第三步:改完不能只执行php start.php reload,必须完整重启:php start.php stop && php start.php start,否则旧监听配置仍驻留在内核中。
第四步:用ss -tuln | grep :5678验证输出里是否含*:5678或0.0.0.0:5678;如果还显示127.0.0.1:5678,说明代码未生效或被其他配置覆盖——【这是最常被忽略的致命错误】。
检查防火墙与云平台安全组
本地telnet 127.0.0.1 5678通 ≠ 外部能连。loopback流量不经过firewalld、iptables或云安全组,所以必须从客户端机器执行telnet your-server-ip 5678实测。
Linux系统防火墙临时放行(测试用):sudo firewall-cmd --add-port=5678/tcp --permanent && sudo firewall-cmd --reload。
阿里云/腾讯云等平台必须进控制台「安全组」,添加入方向规则:协议选TCP,端口填5678,源IP暂设为0.0.0.0/0——别信“已开放”截图,必须手动确认规则状态为“启用”。
Windows/macOS宿主机跑WSL或Docker时,系统级防火墙默认拦截外来连接,需关掉Windows Defender防火墙或在macOS防火墙设置里添加例外。
启用SO_REUSEPORT并调大内核参数
方法一:在start.php中为Worker开启reusePort:
$worker = new Worker('tcp://0.0.0.0:5678');<br>$worker->reusePort = true;
方法二:调大系统级连接队列和本地端口范围(需root权限):
sysctl -w net.core.somaxconn=65535<br>sysctl -w net.ipv4.ip_local_port_range="1024 65535"<br>sysctl -w net.ipv4.tcp_tw_reuse=1
这三行命令缺一不可:somaxconn决定SYN队列长度,ip_local_port_range扩大可用临时端口池,tcp_tw_reuse允许TIME_WAIT状态socket快速复用——【不调这三项,高并发下端口耗尽和SYN丢包必然发生】。
Predis连接超时需禁用读写超时
若Workerman集成Predis访问Redis,运行一段时间后进程崩溃,大概率是Predis客户端因read_write_timeout触发断连。默认值会强制关闭空闲连接,而Workerman长连接模型要求连接持续存活。
创建Predis实例时,显式将超时设为0:
$redis = new Predis\Client('tcp://10.0.0.1:6379?read_write_timeout=0');
注意:不能写成-1,Predis 1.x版本只认0表示永不超时;写错会导致连接池反复重建,加重TIME_WAIT堆积。











