gin.default() 默认包含 logger 和 recovery 两个中间件:logger 打印请求日志,recovery 捕获 panic 防止崩溃;而 gin.new() 不带任何中间件,需手动注册。

gin.Default() 自带哪些中间件?
它默认包含 Logger 和 Recovery 两个中间件,无需手动 Use()。前者打印请求日志(方法、路径、状态码、耗时),后者捕获 panic 并返回 500,防止服务崩溃。
常见错误现象:自己又注册一遍 gin.Logger(),导致日志重复输出;或误以为没开 Recovery,结果 panic 后进程直接退出——其实只要用的是 gin.Default(),它就在那儿。
注意点:
-
gin.New()不带任何中间件,必须显式Use()才有日志和恢复能力 - 如果禁用默认中间件(比如用
gin.New()),又忘了加Recovery,线上 panic 就会 kill 进程 -
Logger输出到标准输出,生产环境建议重定向或替换为结构化日志中间件
自定义中间件里 c.Next() 的位置决定逻辑执行时机
c.Next() 不是“继续往下走”,而是把控制权交给后续中间件或最终 handler;它前面的代码在请求进入时执行,后面的代码在所有后续处理完成、开始写响应时执行——这就是“洋葱模型”的核心。
典型误用:
- 在
c.Next()后面读c.Writer.Status()却得到 0:因为 handler 还没写响应,c.Next()没返回 - 想记录耗时,但把
start := time.Now()放在c.Next()后面:测的是后置逻辑耗时,不是整个请求处理耗时 - 调用
c.Abort()后仍执行c.Next():无效,且可能 panic(c.Next()在已中止链上行为未定义)
正确姿势:前置逻辑 → c.Next() → 后置逻辑(含状态/耗时/响应体检查)
在 Golang 中使用 samber/hot 进行内存缓存,支持 LRU、LFU、TinyLFU、W‑TinyLFU、S3FIFO、ARC、TwoQueue、SIEVE、FIFO 等淘汰算法,提供 TTL、缓存加载器及分片功能。
中间件注册顺序直接影响功能是否生效
Gin 中间件按 Use() 调用顺序串成链,越早注册的越靠外层。顺序错乱会导致鉴权跳过、日志漏打、CORS 头被覆盖等问题。
关键顺序原则:
- 认证类(如
authMiddleware)必须在业务 handler 前,且通常比日志更靠外,否则未登录请求也会被记日志 - CORS 中间件要足够靠前,确保预检请求(OPTIONS)能被正确响应,否则浏览器直接拦截
- 限流中间件应尽早触发,避免无效请求穿透到 DB 或下游服务
- 如果用了
gin.BasicAuth()这类内置中间件,它内部调用c.AbortWithStatusJSON(),一旦失败就终止链,后面中间件不会执行
跨中间件传数据只能用 c.Set()/c.Get(),别依赖局部变量
每个中间件函数都是独立作用域,无法通过闭包或外部变量共享运行时数据(比如从 auth 中间件提取的 user ID,要在日志中间件里打印)。
必须用 c.Set("user_id", uid) 写入,再用 c.Get("user_id") 读取。注意:
-
c.Get()返回interface{}和bool,务必检查第二个返回值,避免 panic - 键名建议统一前缀(如
"auth.user_id")防止冲突 - 不要存大对象(如完整 user struct),避免内存逃逸和 GC 压力;优先存 ID 或必要字段
-
c.MustGet()会 panic,仅用于确定存在且非空的场景,线上慎用
真正容易被忽略的是:c.Set() 写入的数据,在请求结束、context 被回收后就不可访问了——它只活在一个请求生命周期内,这点和全局变量或 sync.Pool 完全不同。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










