直接看%si不能判断非阻塞网络i/o分布健康,关键在核间分布是否均衡;若net_rx单核远超其他核、softnet_stat中dropped或timesqueezed持续增长,说明收包路径失衡,需结合rps与worker绑定优化。

直接看 %si 能快速判断非阻塞网络 I/O 分布是否健康,但不能只盯一个数字——关键在“分布”二字。当软中断集中在少数核、且持续偏高时,说明网络收包路径已失衡,即便 worker 本身是异步非阻塞的,也会因内核侧处理不均而卡住调度、放大延迟、降低吞吐。
先确认 %si 高是否真由 NET_RX 主导
top 中的 si% 是总和值,掩盖了核间差异。必须进到每核视角,并交叉验证来源:
- 运行 top -1(按 1 键),观察各 CPU 核的 si 列,找出明显高于均值的“热点核”(例如 CPU1 si=18%,其余均 ≤2%)
- 执行 cat /proc/softirqs,重点比对 NET_RX、TIMER、SCHED 三列数值:若某核的 NET_RX 占该核总 softirq 超 80%,且绝对值远超其他核(如 150 万 vs 其他核平均 20 万),基本可锁定是网络收包瓶颈
- 检查 /proc/net/softnet_stat:第 2 列(processed)应平稳增长;第 3 列(dropped)或第 4 列(timesqueezed)若持续递增,说明软中断已来不及处理,包被丢弃或强制延后,I/O 分布已失健康底线
结合 worker 模型看“错位”信号
非阻塞网络服务(如 Nginx event、Redis ae、自研 epoll/kqueue 服务)本不该被 CPU 算力卡住,但若出现以下组合,就是分布失衡的典型症状:
- worker 进程 %CPU 使用率不高(us 低),但请求延迟抖动大、P99 明显上扬
- top 中 ksoftirqd/N 进程常年排在 CPU 占用 Top 3,尤其与某个 worker 进程共占同一核
- netstat 或 ss 显示大量连接处于 established 状态,但业务指标(QPS、吞吐)未随连接数线性增长
- perf record -e 'irq:softirq_entry' -C N(N 为热点核号)能抓到密集的 NET_RX 触发,印证收包路径单点承压
用 RPS + worker 绑定验证分布合理性
健康分布的本质是“包在哪核收,worker 就在哪核等”,避免跨核 cache line bouncing 和调度延迟:
- 启用 RPS:向网卡队列写掩码,例如 echo 0f > /sys/class/net/eth0/queues/rx-0/rps_cpus(启用 CPU0–3),确保软中断能分散到多个核
- 同步绑定 worker:Nginx 用 worker_cpu_affinity 0001 0010 0100 1000;自研服务用 taskset -c 0-3 ./app,让 worker 数与 RPS 启用核数一致且一一对应
- 调优后回看 top:各核 si% 应趋近均衡(差值 ≤3%),且整体 si% 下降至 5% 以内;同时 worker 的 us% 上升、延迟下降,说明 CPU 时间真正回到了业务逻辑
警惕假象:si% 低 ≠ 分布健康
有些场景下 si% 看似正常(如全局 3%),但实际隐患更深:
- 流量突发时 si% 瞬间冲高后回落,但 /proc/net/softnet_stat 中 timesqueezed 已累积增长 → backlog 不足,需调大 net.core.netdev_max_backlog
- 多队列网卡未启用 RSS/RPS,所有包默认打到 CPU0,但 CPU0 的 si% 因负载被摊薄(比如有其它高 sy 进程),掩盖了 NET_RX 实际集中 → 必须查 /proc/softirqs 单核明细
- 使用 AF_XDP 或 DPDK 绕过协议栈,此时 si% 极低,但不能误判为“网络 I/O 健康”,那是架构层面的规避,不属于内核 softirq 分析范畴











