{T}

分析服务的特性与进程线程数量规划

服务上线前需评估容器数、CPU 数、进程/线程数,并依据服务特性、目标并发、吞吐、可承受延迟调整。资源给多则闲置浪费,给少则无法工作甚至雪崩。

计算密集型与 I/O 密集型

  • 计算密集型:主要开销在 CPU 算术运算(如深度神经网络、高并发下订单价格计算)。
  • I/O 密集型:主要开销在设备读写(键盘、磁盘、网络、日志、数据库)。I/O 期间 CPU 转去执行其他任务,完成时设备发中断通知 CPU。

I/O 数据搬运通常不消耗 CPU——DMA(Direct Memory Access)模块允许硬件直接写内存。但若用 memcpy 逐字节拷贝数组,则属 CPU 密集。区分类型需结合实际指标,例如用好固态阵列后,数据库查询瓶颈可能转移到缓存搜索(计算)。

CPU 工作指标

CPU 有忙碌、空闲两种状态,虚拟机还可能被宿主"偷走"时间。

CPU 状态

  • 忙碌:执行用户空间程序、内核空间程序、中断程序。
  • 空闲:执行空闲指令(低能耗空转);或等待 I/O 的 I/O Wait。

top 指令第 3 行给出 CPU 占比:

  • us 用户空间;sy 内核空间;ni 调整过优先级的进程;
  • id 闲置;wa I/O Wait 闲置;hi/si 硬/软中断;
  • st 虚拟机被宿主偷走的时间。top 后按 1 可看各核明细。

top 快照

各核状态

负载指标(Load Average)

load average 表示某时刻正在排队的进程数除以 CPU 核数的平均值。大于 1 说明 CPU 相当忙碌。若负载高且 I/O Wait 高,说明 CPU 大量等待 I/O(频繁打日志、读写数据库/网络),可优化为批量读写(一次写 1M 比写百万次 1 字节快,能复用缓存与连接)。详见 /proc/loadavg

DMA

通信量(Traffic)

网络瓶颈可查 /proc/net/dev

网络接口统计

  • 表头分 Interface(网卡)、Receive、Transmit;
  • 指标含 byte(字节)、package(封包)、erros(错误)、drop(超时丢弃)、fifo(FIFO 缓冲错误)、frame(帧错误)。

磁盘指标

I/O 频繁导致磁盘瓶颈时,可用 iotop 看实时读写速度与进程排行:

iotop

空间不足用 df(按挂载的文件系统计算)。细粒度 I/O 看 /proc/diskstats

df

监控平台

Linux 指令可查 CPU/I/O/网络等维度。自建复杂,可用开源工具(如 Taobao System Activity Report / tsar)定时收集,配合 logstash、ELK 做监控分析。

决定进程/线程数量

线程/进程数 = CPU 核数 并非最优。各语言模型不同:

  • Node.js:事件循环(协程式),大量协程复用进程,效率高于线程池;
  • PHP:多进程模型较弱;
  • Java:多线程,线程与内核线程 1:1;
  • Go:轻量级线程(goroutine),多个复用内核线程。

考虑 I/O Wait 的存在:若应用仅用 50% CPU 时间、另 50% 等待 I/O,则 1 个 CPU 可同时承载 2 个线程。一般模型下,单线程 I/O 占比为 P,n 个线程都在等待 I/O 的概率为 (P^n),CPU 利用率 = (1 - P^n)。理论上 P=50% 时 2 个线程即满负荷,但实际调度为分时行为,会有闲置。

因此实际线程/进程数通常超过核数。建议以"核数 × 3"起步做真实压测,据结果调整:

  • 瓶颈在 CPU(load average 高):优化 I/O Wait,或采用延迟读写、减少读写;
  • idle 高、CPU 闲置多:增加线程。

小结

  • 计算密集型:线程/进程数接近核数,负载高时留 1 核给 OS。
  • I/O 密集型:开大于核数的线程/进程。
  • 语言特性影响模型:Node.js 可长期用"核数-1"进程;Java 线程池需大于核数。
  • 核心原则:上线前必须压测,并持续监控不同并发下的资源表现。