一、在编译阶段(go build)做不到限制go程序能使用的CPU核数
因为在编译阶段(go build):
- 不知道程序将运行在哪台机器
- 不知道有多少 CPU、是否在容器中
- Go 编译产物是 通用二进制,不绑定运行环境
所以 不存在编译期的 CPU 限制选项。
编译参数:
- -gcflags
- -ldflags
- GOARCH / GOOS
都不能限制 CPU 核数。
二、官方 & 推荐的运行时方式(进程内)
1 环境变量(最常用)
GOMAXPROCS=4 ./app
限制4个CPU核数,等价于代码:runtime.GOMAXPROCS(4)
无需改代码
进程启动时生效
Go 1.5+ 支持
Go 1.21+ 默认会自动感知容器 CPU 限额
2 代码里设置
runtime.GOMAXPROCS(4)
只能影响 Go 调度器
不限制 OS 线程的创建(那是另一回事)。
三、操作系统 / 容器层(更“硬”的限制)
1 Docker / Kubernetes(强烈推荐)
Docker:
docker run --cpus=2 my-go-app
Kubernetes:
resources:
limits:
cpu: "2"
Go runtime 会:
- 看到 cgroup 限制
- 自动设置 GOMAXPROCS = 2(Go 1.21+)
2 Linux taskset(CPU 亲和性)
taskset -c 0,1 ./app
限制进程只能跑在 CPU 0、1
对所有语言生效
Go runtime 会“被动服从”
3 cgroups(底层方式)
echo 200000 > cpu.cfs_quota_us
echo 100000 > cpu.cfs_period_us
容器本质用的就是这种方式
最底层、最硬核
