Skip to content

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.goPanic 恢复拦截器
middleware/interceptor_test.go链式调用测试、Recovery 测试

运行

bash
go run ./day8-middleware/example/
go test -v ./middleware/