go test -race 必须在 CI 中默认启用,它是并发安全的底线保障;需用 go test -race -coverprofile=coverage.out ./... 覆盖全部子模块,避免漏检,且禁止使用 time.Sleep,改用 sync.WaitGroup 或 channel 控制时序。

go test 和 -race 必须在 CI 中默认启用
Go 的竞态检测器(-race)不是可选插件,是并发安全的底线保障。本地开发常因性能忽略它,但 CI 环境必须强制开启——否则上线后偶发 panic 很难复现。
- CI 脚本中统一用
go test -race -coverprofile=coverage.out ./...,不要只跑./,漏掉子模块会掩盖问题 - 覆盖率报告建议用
go tool cover -func=coverage.out提取函数级数据,比行覆盖率更能暴露逻辑盲区 - 避免在测试里用
time.Sleep模拟等待,改用sync.WaitGroup或 channel 控制时序,否则-race无法捕获真实竞争 - GitHub Actions 中若用矩阵构建多版本 Go,每个 job 都要单独跑
-race,1.21+ 版本对 race 检测有行为差异
GOOS/GOARCH 交叉编译不能只写死 linux/amd64
生产环境早就不止一种架构:ARM64 的云主机、Apple Silicon 的 CI 构建机、甚至嵌入式设备。只编译 GOOS=linux GOARCH=amd64 会让部署卡在第一步。
- 用 Makefile 或 GitHub Actions 矩阵定义常见组合:
linux/amd64、linux/arm64、darwin/amd64、darwin/arm64 - 二进制名建议带平台后缀,例如
myapp-linux-amd64,避免覆盖或误传 - 加
-ldflags="-s -w"去除调试信息,能减小 30%+ 体积,尤其对容器镜像大小敏感 - 注意
CGO_ENABLED=0:默认开启时会链接 libc,在 Alpine 镜像里直接报错;CD 流程中应显式设为 0
Docker 多阶段构建里,build 阶段用 golang:alpine 要小心
很多教程直接抄 golang:alpine 作构建基础镜像,但它默认不带 git、ca-certificates,go mod download 或私有仓库依赖会静默失败。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 构建阶段推荐用
golang:1.21-alpine+ 显式安装依赖:apk add --no-cache git ca-certificates - 最终运行阶段必须用
scratch或distroless/static,别用alpine——它带 shell,是安全审计红线 -
COPY --from=builder /workspace/myapp /myapp这类路径要和WORKDIR严格匹配,Docker 缓存失效时容易复制空文件 - 镜像标签别只用
latest,优先用$GITHUB_SHA或${{ github.event.release.tag_name }},方便回滚和 trace
CD 阶段用 ssh-action 推送二进制前必须校验指纹
自动化部署最危险的环节不是构建失败,而是把错误二进制推到线上且没感知。直接 scp 或 ssh-action 执行命令,跳过校验等于裸奔。
立即学习“go语言免费学习笔记(深入)”;
- 在部署前加一步:用
ssh连目标机器执行sha256sum /opt/myapp,和本地sha256sum myapp-linux-amd64对比 -
appleboy/ssh-action@v1.0.0支持script_stop:true,任一命令失败即中断,别让它默默继续 - 生产部署务必加人工审批(GitHub Environments 的 environment protection rules),哪怕只按一次确认键
- 敏感操作如
systemctl restart myapp,应包装成幂等脚本,支持重复执行不翻车
go build 成功不代表服务能启,docker push 成功不代表镜像能跑,ssh 连上不代表进程活着——每层都要有明确的健康断言。

















