CPU Core(CPU 核心)
CPU 核心是处理器中独立执行指令的物理计算单元。一个 CPU 可以包含多个核心(多核处理器),每个核心都能独立运行一个线程。
- 单核:一次只能执行一个任务,通过时间片轮转模拟并发
- 多核:每个核心可以并行执行不同的任务,真正意义上的并行计算
- 超线程(Hyper-Threading):一个物理核心可以虚拟成两个逻辑核心,提高资源利用率
┌──────────────────────────────┐
│ CPU 芯片 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Core0│ │Core1│ │Core2│ │
│ │ │ │ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Core3│ │Core4│ │Core5│ │
│ └─────┘ └─────┘ └─────┘ │
└──────────────────────────────┘
在云服务器上,你购买的 2 vCPU 就是 2 个虚拟核心,对应宿主机上的 2 个超线程或物理核心。
CPU 分片(CPU Time Slicing / CPU Quota)
CPU 分片指的是在多租户环境下,将一个物理 CPU 核心的计算时间按比例分配给不同的进程或容器。
两种常见机制
时间片轮转(Time Slicing)
操作系统调度器让多个进程轮流使用 CPU,每个进程分配一个时间片(通常几毫秒)。对于单核 CPU 来说,并发是假的——本质是快速切换,人眼看起来像同时运行。
配额限制(CPU Quota / CFS Bandwidth Control)
Linux 内核的 CFS(Completely Fair Scheduler)支持按比例分配 CPU 时间:
# Docker 中限制 CPU
docker run --cpus=1.5 myapp # 最多使用 1.5 个核心的算力
docker run --cpu-shares=512 myapp # 相对权重
# K8s 中
resources:
requests:
cpu: "250m" # 0.25 核,即 250 millicpu
limits:
cpu: "500m" # 最多 0.5 核
250m 表示每 100ms 的周期中,最多使用 25ms 的 CPU 时间。这就是"分片"的具体体现。
Worker(执行单元)
Worker 是一个上层抽象概念,在不同场景下含义完全不同。它本质上是对「执行单元」的封装,让你不用直接操心底层线程。
Worker 与线程的关系
线程(Thread)—— OS 级,CPU 真正执行的东西
↓ 包装
Worker —— 框架/平台级,对执行单元的封装
↓ 可能有多个
Worker Pool —— 并发执行一组任务
线程是底层实现,Worker 是上层抽象。同一个 Worker 内部可能跑在一个线程上,也可能跨多个线程——取决于平台实现,对使用者透明。
浏览器:Web Worker
浏览器中的 Worker ≈ 后台线程。有独立的执行环境,不能直接访问 DOM,通过 postMessage 和主线程通信。
// 主线程
const worker = new Worker('task.js');
worker.postMessage(data);
// task.js(Worker 线程)
self.onmessage = (e) => {
// 独立执行,不阻塞 UI
const result = heavyCompute(e.data);
self.postMessage(result);
};
- 一个 Worker ≈ 一个后台线程,浏览器帮你管理线程池
- 典型场景:图片处理、加密、大量计算,避免卡 UI
- 还有 SharedWorker(多个页面共享)和 ServiceWorker(离线缓存、拦截请求)
Serverless:函数执行实例
在 Serverless 架构中,Worker 是实际执行函数代码的运行时实例。
用户请求 → API Gateway → 调度器 → Worker 实例
↓
执行函数代码,返回结果
这里的 Worker 不是线程,而是隔离的运行时环境(V8 Isolate / 容器)。每个请求可能分配一个独立 Worker,底层可能跑在某个进程的线程池上,但对开发者完全透明。
- 冷启动:首次请求时需要启动运行时环境,会有延迟
- 热启动:Worker 实例被复用,直接执行代码,延迟低
- 并发实例:每个请求通常分配独立的 Worker,天然隔离
- 生命周期短:执行完就销毁(或保留一段时间用于热启动)
典型实现:AWS Lambda、Cloudflare Workers、Vercel Functions。
Node.js:Worker Threads
Node.js 的 worker_threads 模块让你在服务端也能用多线程。每个 Worker 是一个独立的 V8 实例,有自己的事件循环。
const { Worker } = require('worker_threads');
const worker = new Worker('./heavy-task.js');
worker.on('message', (result) => {
console.log('计算结果:', result);
});
worker.postMessage({ data: largeArray });
- 和 Web Worker 类似,但跑在服务端
- 解决 Node.js 单线程 CPU 密集型任务的瓶颈
- 不共享内存(除非用 SharedArrayBuffer)
通用概念:Worker Pool
一组预创建的 Worker(线程/进程)等着接活,避免反复创建销毁的开销。
任务队列 → [Worker1] [Worker2] [Worker3] → 结果
- Go 的 goroutine pool、Java 的 ThreadPoolExecutor、Python 的 ProcessPoolExecutor 都是这个模式
- 线程池大小通常设为 CPU 核心数(CPU 密集)或更大(IO 密集)
总结对比
| 场景 | Worker 含义 | 底层实现 | 生命周期 |
|---|---|---|---|
| 浏览器 Web Worker | 后台线程 | OS 线程 | 页面存活期间 |
| Serverless | 隔离运行时实例 | V8 Isolate / 容器 | 请求级,秒~分钟 |
| Node.js worker_threads | 独立 V8 实例 | OS 线程 | 手动管理 |
| Worker Pool | 预创建的任务执行者 | 线程/进程 | 应用级,长期复用 |
一句话:Worker 是你看到的执行单元,线程是它背后真正跑的东西。
Pod(容器组)
Pod 是 Kubernetes 中最小的可部署单元,一个 Pod 可以包含一个或多个紧密耦合的容器。
┌─────────────────────────────┐
│ Pod │
│ ┌──────────┐ ┌──────────┐ │
│ │ 主容器 │ │ sidecar │ │
│ │ (Nginx) │ │ (日志收集)│ │
│ └──────────┘ └──────────┘ │
│ 共享网络: 同一 IP │
│ 共享存储: 卷挂载 │
└─────────────────────────────┘
为什么需要 Pod?
- 共享网络:Pod 内的容器共享同一个 IP 地址和端口空间,可以通过
localhost互相通信 - 共享存储:容器之间可以共享 Volume,方便数据交换
- 生命周期绑定:Pod 内的容器同生共死,一起调度到同一台节点
常见用法
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: log-agent
image: fluentd
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
emptyDir: {}
Pod vs 容器 vs 节点
集群 (Cluster)
└── 节点 (Node) —— 一台物理机或虚拟机
└── Pod —— 一组容器
└── 容器 (Container) —— 一个进程
总结
| 概念 | 本质 | 层级 |
|---|---|---|
| CPU Core | 物理/虚拟计算单元 | 硬件层 |
| CPU 分片 | CPU 时间的按比例分配 | 操作系统/调度层 |
| Worker | 执行单元的抽象封装 | 应用运行时层 |
| Pod | 一组共享资源的容器 | 容器编排层 |
从底层到上层:Core → 分片 → Worker/Pod → 你的应用。理解这些概念,就能更好地做容量规划和成本优化。