第18章:限流、压缩与其他常用中间件
本章目标
学完本章后,你将能够:
- 使用令牌桶算法实现限流
- 配置 Gzip 压缩提升传输效率
- 使用安全头中间件保护应用
- 组合常用的中间件搭建生产级 Gin 服务
前置知识
- 需要先学习:第16-17章(自定义中间件、CORS)
18.1 Gzip 压缩
bash
go get github.com/gin-contrib/gzipgo
import "github.com/gin-contrib/gzip"
r.Use(gzip.Gzip(gzip.DefaultCompression))
// 响应体 > 默认阈值时自动压缩,减少传输量 70%+18.2 安全头中间件
bash
go get github.com/gin-contrib/securego
import "github.com/gin-contrib/secure"
r.Use(secure.New(secure.Config{
SSLRedirect: true,
STSSeconds: 315360000,
STSIncludeSubdomains: true,
FrameDeny: true,
ContentTypeNosniff: true,
BrowserXssFilter: true,
}))
// 自动添加:X-Frame-Options, X-XSS-Protection 等安全头18.3 请求大小限制中间件
go
func MaxBodySize(maxBytes int64) gin.HandlerFunc {
return func(c *gin.Context) {
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxBytes)
c.Next()
}
}
// 限制请求体最大 1MB
r.Use(MaxBodySize(1 << 20))18.4 生产环境中间件组合
go
func SetupProductionRouter() *gin.Engine {
r := gin.New()
// 1. 安全相关(最外层)
r.Use(secure.New(secure.DefaultConfig()))
r.Use(CORSMiddleware())
// 2. 性能相关
r.Use(gzip.Gzip(gzip.DefaultCompression))
r.Use(MaxBodySize(10 << 20)) // 10MB
// 3. 追踪与日志
r.Use(TraceID())
r.Use(gin.Logger())
r.Use(gin.Recovery())
// 4. 业务中间件
r.Use(RateLimiter(100, time.Minute)) // 全局限流
return r
}18.5 中间件顺序建议
请求 →
1. 安全中间件(CORS, Secure Headers)
2. 性能中间件(Gzip, BodyLimit)
3. 追踪中间件(TraceID, Logger)
4. Recovery(捕获 panic)
5. 认证中间件(Auth, JWT)
6. 业务中间件(限流,权限)
7. 路由处理函数(Handler)
→ 响应常见错误
错误1:Gzip 压缩了小文件
go
// ⚠️ 小于 1KB 的文件压缩后可能更大
// ✅ 设置合理阈值
gzip.Gzip(gzip.BestSpeed, gzip.WithExcludedPaths([]string{"/api/"}))错误2:安全头与 Nginx 重复
如果你用了 Nginx 反向代理,安全头可能在 Nginx 层已经设置了,Gin 层不需要重复。
本章小结
- 生产环境中间件组合:安全 → 性能 → 追踪 → Recovery → 认证 → 业务
- Gzip 大幅减少 JSON 传输量(70%+)
- Secure Headers 防 XSS/点击劫持等攻击
- 限流保护服务不被突发流量打垮
练习题
- 集成 Gzip 中间件,对比启用前后的响应大小。
- 配置 secure 中间件,观察响应头的变化。
- 写一个限制请求体大小的中间件。
- (思考题)中间件顺序为什么重要?CORS 为什么要放在 Auth 前面?