发布于2026-07-07 阅读(0)
扫一扫,手机访问
如果在 Swoole 文档里搜 open_cpu_affinity,大概率会空手而归——它压根不存在。这其实是一个流传已久的“幽灵配置”,大概率是早期社区笔记混淆了 Nginx 的 worker_cpu_affinity,或者是某篇文档的手误。真正管用的开关只有一个:process_cpu_affinity。说一个关键结论:Swoole 的 CPU 亲和性配置,名字千万别写错,否则费了半天劲配置,实际上根本就没生效。
open_cpu_affinity?你猜怎么着?这个配置键在 Swoole 的官方源码、PHP 扩展注册参数、php --ri swoole 输出、以及 Swoole 5.x 的 Server->set() 支持键名里,全都找不到。它更像是社区笔记里的一次笔误——可能是把 process_cpu_affinity 手误写成了 open_...。实际被 Swoole 内核识别并生效的配置只有两个:
process_cpu_affinity:布尔值,控制是否开启 Worker 进程的自动 CPU 核心轮转绑定swoole_set_cpu_affinity():运行时函数,用于在 WorkerStart 回调中手动指定绑定哪些逻辑 CPUprocess_cpu_affinity = true 时到底做了什么?设为 true 后,Swoole 主进程在 fork 出每个 Worker 后,会立刻调用 sched_setaffinity() 系统调用,把这个 Worker 钉在一个独占的逻辑 CPU 上。分配规则很简单:Worker ID 0 绑 CPU 0,Worker ID 1 绑 CPU 1,以此类推,超了就循环取模。这个过程是不可逆的,而且系统也不会检查那个 CPU 到底存不存在、是不是已经超载了。
有几个点需要警惕:
onTask 回调里手动调用 swoole_set_cpu_affinity()。worker_num 大于逻辑 CPU 总数(比如 8 个 Worker 跑在一台 4 核 8 线程的机器上),就会出现多个 Worker 抢同一个逻辑 CPU 的情况,亲和性设置就近乎失效了。想要更精细的控制,可以在 WorkerStart 回调里用 swoole_set_cpu_affinity([0, 2]),这样就能让某个 Worker 只在 CPU 0 和 CPU 2 上运行(软亲和)。对比之下,process_cpu_affinity => true 是硬邦邦的单核绑定(硬亲和),灵活性差一些。
但手动绑定的坑也很实在:
[99])不会触发报错,亲和性就默默地没生效。swoole_set_cpu_affinity() 会静默失败(返回 false),因为这个函数只对子进程有效。/proc/cpuinfo 显示的 CPU 逻辑核数可能和宿主机不一致,swoole_cpu_num() 的返回值也可能不准。稳妥的做法是结合 cgroups 的资源限制,再显式指定 CPU 编号。别光看配置项的状态,用系统命令验证才是王道:
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 照样能让你性能跳水。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8