swoole中不存在open_cpu_affinity配置项,正确配置是process_cpu_affinity;设为true时自动将各worker按id顺序绑定到对应cpu核心,需配合worker_num≤逻辑cpu数以避免争抢,手动绑定则用swoole_set_cpu_affinity()在workerstart中指定。

open_cpu_affinity 这个配置项并不存在于 Swoole 的任何稳定版本中(包括 4.x 和 5.x),它是常见误传或文档笔误——你真正要找的是 process_cpu_affinity。
为什么搜不到 open_cpu_affinity?
官方源码、PHP 扩展注册参数、php --ri swoole 输出、以及所有 Swoole 5.x 的 Server->set() 支持键名中,均无 open_cpu_affinity。它可能是早期社区笔记混淆了 Nginx 的 worker_cpu_affinity 或旧版 Swoole 文档的错别字(比如把 process_cpu_affinity 手误写成 open_...)。
实际生效且被内核识别的配置只有:
-
process_cpu_affinity:布尔值,控制是否开启 Worker 进程的自动 CPU 核心轮转绑定 -
swoole_set_cpu_affinity():运行时函数,用于在WorkerStart回调中手动指定绑定哪些逻辑 CPU
process_cpu_affinity = true 时到底做了什么?
当设为 true,Swoole 主进程会在 fork 出每个 Worker 后,**立即调用 sched_setaffinity() 系统调用**,将该 Worker 绑定到一个独占的逻辑 CPU 上(按顺序分配:Worker ID 0 → CPU 0,Worker ID 1 → CPU 1……循环取模)。这个过程不可逆,且不检查 CPU 是否真实存在或已超载。
关键点:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 只作用于 Worker 进程,Task 进程默认不参与,除非你在
onTask里手动调用swoole_set_cpu_affinity() - 若
worker_num > 逻辑 CPU 总数(例如 8 个 Worker 跑在 4 核 8 线程机器上),会出现多个 Worker 共享同一逻辑 CPU,失去亲和性意义 - 它不会阻止系统调度器把其他进程塞进同一个 CPU,但能确保你的 Worker 不会被“踢走”
手动绑定比自动绑定更灵活,但也更危险
在 WorkerStart 回调里用 swoole_set_cpu_affinity([0, 2]) 可以让某个 Worker 只在 CPU 0 和 CPU 2 上运行(软亲和),而 process_cpu_affinity => true 是硬绑定单核(硬亲和)。
容易踩的坑:
- 传入空数组或非法编号(如
[99])会导致调用失败,但 Swoole 不报错,进程照常运行——只是亲和性没生效 - 在 Manager 进程或主进程中调用
swoole_set_cpu_affinity()会静默失败(返回false),因为该函数仅对子进程有效 - Linux 容器环境(如 Docker)中,
/proc/cpuinfo显示的逻辑 CPU 数可能与宿主机不一致,swoole_cpu_num()返回值可能不准,建议结合cgroups限制 + 显式指定编号
验证是否真的绑定了?
不要只信配置,用系统命令确认:
ps -eo pid,args,psr | grep "php.*server"
输出中的 psr 列就是当前进程正在运行的逻辑 CPU 编号。如果看到多个 Worker 都挤在 psr=0,说明 process_cpu_affinity 没生效,或者 worker_num 设得太大。
真正的瓶颈往往不在“有没有绑定”,而在于你是否把高 I/O 协程、CPU 密集计算、日志刷盘这些行为混在同一个 Worker 里——哪怕绑死 CPU,缓存污染和 TLB miss 一样会让性能掉下来。










