go打包太慢
一、先诊断瓶颈30 秒bash# 1. 总耗时 time go build ./... # 2. 看哪步最慢-x 输出编译全过程 time go build -x ./cmd/api 21 | ts -i %.s # 需安装 moreutils # 3. 链接阶段单独测通常是大头 time go build -ldflags-v ./cmd/api 21 | grep -E (compile|link) # 4. 包编译并发度 go build -debug-actiongraphaction.json ./... # 然后用浏览器打开 https://ui.perfetto.dev/ 分析二、立即可做的优化1. 链接加速效果最明显bash# 禁用内联和优化开发环境 go build -gcflags-N -l ./cmd/api # 调试模式编译快但运行慢 # 生产环境用 gold/lld 替代默认 ld sudo apt install lld go build -ldflags-extldflags-fuse-ldlld -s -w ./cmd/api2. 并行拉满bash# 默认并发等于 CPU 数手动指定更多IO 瓶颈时有效 go build -p $(nproc) ./...3. 模块缓存持久化CI 环境关键bash# 确认缓存位置 go env GOCACHE # 通常是 ~/.cache/go-build go env GOPATH # 模块在 ~/go/pkg/mod # CI 中务必缓存这两个目录三、代码结构优化治本问题一个go build ./...编译全工程改为按需编译bash# 只编译你正在开发的服务 go build ./cmd/api-server # 甚至只编译单个包测试 go test ./internal/user/...如果必须全量编译拆分入口plainproject/ ├── cmd/ │ ├── api-server/ # go.mod 独立不先共用根 go.mod │ ├── worker/ │ └── admin/根目录 go.mod 不变但构建脚本只编译变更的bash#!/bin/bash # build.sh - 增量编译 LAST_COMMIT$(cat .last_build_commit 2/dev/null || echo ) CURRENT$(git rev-parse HEAD) if [ $LAST_COMMIT $CURRENT ]; then echo 无变更跳过编译 exit 0 fi # 找出变更的服务 for cmd in cmd/*/; do if git diff --name-only $LAST_COMMIT | grep -q ^$cmd; then echo 编译 $cmd ... go build ./$cmd fi done echo $CURRENT .last_build_commit四、Go 1.24 新特性缓存编译bash# 确保版本较新 go version # 1.21 缓存机制大幅改进 # 显式使用构建缓存默认已开启 go build -buildvcsfalse ./... # 跳过 VCS 信息收集省几秒五、终极方案拆模块go.work如果代码 20 万行根 go.mod 依赖爆炸bash# 1. 把独立服务拆出独立模块 mkdir services/api cd services/api go mod init github.com/yourco/project/services/api # 2. 根目录创建 workspace cd ../.. go work init . go work use ./services/api ./services/worker ./pkg/common效果修改services/api不会使services/worker的编译缓存失效。六、快速检查清单表格检查项命令目标Go 版本go version≥ 1.21缓存位置go env GOCACHE确保有写权限且空间充足模块缓存go env GOPATH/pkg/mod不被清理链接器go build -ldflags-v看是否用了 lld全量编译必要—能否改为按需编译关键问题go build ./...耗时多久time的结果是开发时每次保存都慢还是 CI 打包慢代码大概多少行find . -name *.go | xargs wc -l | tail -1给我time go build -x ./... 21 | head -20的输出能精确定位瓶颈。