生产环境禁用 gin.default(),因其默认 logger 和 recovery 中间件在高并发下成瓶颈且隐藏错误堆栈;必须改用 gin.new() + 自定义中间件,并手动构造 *http.server 实现超时、优雅关闭与 tls 控制。

开发环境别用 gin.Default() 直接上线
它默认加载 Logger() 和 Recovery(),调试时方便,但生产里会埋雷:Logger() 在高并发下自身成瓶颈;Recovery() 捕获 panic 后不透出堆栈,错误现场被吞掉,排查变困难。
- 开发阶段可继续用
gin.Default(),但必须清楚它只是“快速启动”,不是“生产就绪” - 生产环境务必改用
gin.New(),再按需加中间件:比如只加Recovery(),日志交给zap或logrus单独管理 - 禁用
Recovery()不等于放弃容错——容器环境下 panic 会触发进程重启,反而更早暴露问题,比静默失败更可控
r.Run() 绑定 0.0.0.0:8080 是生产大忌
默认监听所有网卡,Docker 容器里可能意外暴露给宿主机甚至外网。更严重的是,它绕过了超时控制、优雅关闭、TLS 配置等关键能力。
- 必须自己构造
*http.Server:例如srv := &http.Server{Addr: ":8080", Handler: r, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second} - HTTPS 不能只靠
r.RunTLS()—— 它不支持自动证书续签,生产应由反向代理(如 Nginx 或 Traefik)终止 TLS - 进程退出前必须调
srv.Shutdown(),否则正在处理的请求会被 kill -9 式中断
路由参数、查询参数、表单数据三者绝不能混用
c.Param()、c.Query()、c.PostForm() 来源完全不同,拿错就返回空或 panic,Gin 不做运行前校验,只能靠你写对。
-
c.Param("id")只从路径匹配,如/user/:id→/user/123才能取到"123" -
c.Query("page")只取 URL 查询参数,/list?page=2→"2";重复 key(如?a=1&a=2)只返回第一个值 -
c.PostForm("name")仅适用于application/x-www-form-urlencoded;JSON 请求必须用c.ShouldBindJSON(&v),否则永远拿不到数据
Docker 镜像里别打包 config 文件和 root 权限
配置硬编码或随镜像发布,等于把数据库密码、密钥等敏感信息塞进镜像层,违反最小权限与安全隔离原则。
- 构建时用多阶段 Dockerfile,把
configs/单独 COPY 到运行镜像,且挂载为 volume 或 ConfigMap - 镜像内禁止以 root 运行:用
adduser创建非 root 用户,再USER appuser - 编译时加
CGO_ENABLED=0和-ldflags="-w -s",剥离符号和调试信息,减小体积并降低攻击面
真正难的不是加功能,是删东西——删掉默认中间件、删掉裸跑监听、删掉混用参数的习惯、删掉镜像里的敏感配置。这些“删法”,才是生产安全的起点。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











