go程序必须以pid 1运行并同时监听os.interrupt和syscall.sigterm,用带缓冲channel接收信号,调用http.server.shutdown配合25秒context超时,再按反向依赖顺序关闭db、grpc等资源,k8s需配terminationgraceperiodseconds=30、prestop为exec类型、cmd为["./main"]。

必须让 Go 二进制作为 PID 1 进程,并在代码里同时监听 os.Interrupt 和 syscall.SIGTERM,否则 K8s 发出的终止信号根本收不到,http.Server.Shutdown() 就没机会执行。
Go 程序里怎么写 Shutdown 逻辑才不丢请求
核心是三件事:信号捕获、带超时的 Shutdown()、下游资源手动关闭顺序。漏掉任一环,都会出现连接被砍、goroutine 泄漏或进程卡死。
-
signal.Notify的 channel 必须带缓冲:make(chan os.Signal, 1);不加缓冲,第一个信号可能直接丢失 -
srv.Shutdown()必须传入context.WithTimeout(ctx, 25*time.Second)——不能用context.Background(),否则会无限等待;K8s 默认terminationGracePeriodSeconds: 30,你的超时得留出至少 5 秒余量 -
srv.Shutdown()返回后,立刻调cancel(),否则 context 泄漏,监听ctx.Done()的 goroutine 会一直挂着 - 别只关 HTTP server:
*sql.DB.Close()、grpcServer.GracefulStop()、Kafka consumer shutdown 都得手动做,且顺序必须反向依赖(先停消费者,再等 DB 连接归还,最后关 HTTP)
K8s YAML 里哪些字段不配就等于没优雅停机
就算 Go 代码写对了,YAML 配错照样秒退。常见失效点集中在三处:主进程不是 PID 1、preStop 没生效、探针路径不匹配。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 容器
command必须是["./main"],不能是["sh", "-c", "./main"]—— 后者让sh成为 PID 1,它不转发信号给子进程 -
preStop必须用exec类型,比如:exec: {command: ["/bin/sh", "-c", "sleep 1"]};httpGet类型无法保证在SIGTERM前执行,纯属摆设 -
livenessProbe和readinessProbe的httpGet.path必须和代码里注册的完全一致,比如 YAML 写/healthz,代码却只挂了/health,探针永远 404,Pod 直接被反复杀 -
terminationGracePeriodSeconds建议显式设为30,和代码里context.WithTimeout(..., 25*time.Second)形成配合
Dockerfile 怎么写才能让优雅停机真正起作用
镜像构建阶段看着无关紧要,但一旦用了错误基础镜像或启动方式,优雅停机逻辑会在运行时静默失效。
- 必须用多阶段构建:第一阶段
FROM golang:1.22-alpine编译,第二阶段FROM alpine:latest或scratch运行;用FROM golang直接跑,镜像里带着整个 Go 工具链,体积大、攻击面宽、还可能干扰信号传递 - 编译时必须加
CGO_ENABLED=0,否则静态链接失败,运行时依赖 libc,scratch镜像直接 panic - 最终
CMD必须是二进制路径,比如CMD ["./main"];写成CMD ["go", "run", "main.go"]是开发模式,上线后会把 Go runtime 打进镜像,且无法正确接收信号 - 如果用了 cgo(如
sqlite3),就不能用scratch,得保留alpine并apk add对应依赖,否则运行时报no such file or directory
最容易被忽略的是:Shutdown 不是单点动作,而是信号捕获、HTTP 层排空、DB/gRPC/消息队列等资源按序关闭组成的闭环。任何一环缺失,比如忘了调 db.Close() 或 grpcServer.GracefulStop(),都可能在日志里看不到报错,但上线后某次滚动更新就会突然出现连接泄漏或数据写入中断。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










