主题
Day 8 — 中间件与拦截器(Middleware)
学习目标
提供可扩展的请求处理管线,支持日志、鉴权、限流等横切关注点的统一处理。
核心概念
拦截器模式
借鉴 gRPC 的 Interceptor 设计,miniRPC 提供两种拦截器:
go
// 服务端拦截器
type ServerInterceptor func(ctx context.Context, req interface{},
info *UnaryServerInfo, handler HandlerFunc) (interface{}, error)
// 客户端拦截器
type ClientInterceptor func(ctx context.Context, method string,
req, reply interface{}, invoker Invoker) error洋葱模型
拦截器链按「洋葱模型」执行:
请求 → Recovery.before → AccessLog.before → Handler → AccessLog.after → Recovery.after → 响应内置拦截器
| 拦截器 | 作用 |
|---|---|
AccessLogServerInterceptor | 记录方法名、耗时、错误 |
AccessLogClientInterceptor | 记录客户端调用日志 |
RecoveryServerInterceptor | 捕获 panic,打印堆栈,返回错误 |
如何编写自定义拦截器
go
func MyInterceptor() middleware.ServerInterceptor {
return func(ctx context.Context, req interface{},
info *middleware.UnaryServerInfo, handler middleware.HandlerFunc) (interface{}, error) {
// 前置逻辑
log.Println("before:", info.FullMethod)
resp, err := handler(ctx, req)
// 后置逻辑
log.Println("after:", info.FullMethod)
return resp, err
}
}
// 组合多个拦截器
chain := middleware.ChainServerInterceptors(
middleware.RecoveryServerInterceptor(),
MyInterceptor(),
middleware.AccessLogServerInterceptor(),
)关键代码
| 文件 | 说明 |
|---|---|
middleware/interceptor.go | 拦截器接口、Chain 函数 |
middleware/accesslog.go | 日志拦截器 |
middleware/recovery.go | Panic 恢复拦截器 |
middleware/interceptor_test.go | 链式调用测试、Recovery 测试 |
运行
bash
go run ./day8-middleware/example/
go test -v ./middleware/