swoole worker 进程不绑定端口,端口由主 server 单独监听并共享;所谓“固定端口”实为误解,真正可控的是连接分发策略——可通过 $server->bind($fd, $worker_id) 强制指定连接归属 worker,或配置 dispatch_mode => 2 实现基于客户端 fd 的哈希固定分发;worker_name 仅影响进程显示名,与端口和路由无关。

为什么不能直接“固定端口”给Worker进程
Swoole 的 worker_num 进程不绑定端口,端口只由主 Server 实例监听一次,所有 Worker 共享这个 socket。所谓“固定端口的 Worker”,实际是误解——真正能控制的是连接分发策略、连接绑定目标 Worker、或让特定请求始终落到同一 Worker 上处理。
用 server->bind() 把客户端连接绑定到指定 Worker
这是最接近“固定端口对应 Worker”的做法:虽然端口仍是共享的,但你可以让某个客户端连接($fd)后续所有事件都由你指定的 $worker_id 处理。前提是必须在 Worker 进程内调用,且只能在 onConnect 或 onReceive 等回调中执行。
-
$server->bind($fd, $worker_id)必须确保$worker_id在0到worker_num - 1范围内 - 绑定后不可更改,也不能跨进程调用(比如在 Manager 或 Task 进程里调用会失败)
- 常见用途:WebSocket 长连接需状态保持、避免 session 锁竞争、调试时隔离流量
- 副作用:破坏负载均衡,高并发下可能让某个 Worker 过载
示例:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
$server->on('Connect', function ($server, $fd) {
// 假设只把前 100 个连接绑定到 worker_id = 0
if ($server->connection_info($fd)['from_id'] bind($fd, 0);
}
});
用 dispatch_mode => 2 实现连接级固定分发
该配置让 Swoole 根据客户端 $fd 哈希值决定分配哪个 Worker,相同 $fd(即同一 TCP 连接)永远进同一个 Worker。它比手动 bind() 更轻量,无需业务逻辑干预,适合无状态但需连接亲和的场景(如某些长轮询服务)。
- 配置位置在
server->set()中:'dispatch_mode' => 2 - 不依赖回调,启动即生效
- 注意:仅对新连接生效;已建立连接不受影响
- 和
bind()不冲突,但优先级更低(bind()是强制覆盖)
别误用 worker_name 当作“端口标识”
worker_name 只是修改进程显示名(ps aux 里看到的),和网络端口、连接路由完全无关。有人试图靠改名来“区分端口用途”,结果发现根本不影响请求分发逻辑。
- 设置方式:
'worker_name' => 'api_worker'(全局基础名) - 配合
cli_set_process_title("api_worker_{$worker_id}")可带编号显示 - 纯运维辅助手段,对请求流向无任何控制力
真正需要连接固定路由时,盯紧 bind() 和 dispatch_mode,别被进程名误导。后者只是让你看清谁在干活,不是让它去决定谁该干活。










