Kratos 内置了一系列的 middleware(中间件)用于处理 logging、 metrics 等通用场景。您也可以通过实现 Middleware 接口,开发自定义 middleware,进行通用的业务处理,比如用户登录鉴权等。

内置中间件

相关代码均可以在middleware目录下找到。

  • logging: 用于请求日志的记录。
  • metrics: 用于启用metric。
  • recovery: 用于recovery panic。
  • tracing: 用于启用trace。
  • validate: 用于处理参数校验。
  • metadata: 用于启用元信息传递

生效顺序

一个请求进入时的处理顺序为Middleware注册的顺序,而响应返回的处理顺序为注册顺序的倒序。

  1. ┌───────────────────┐
  2. MIDDLEWARE 1
  3. ┌────────────────┐│
  4. MIDDLEWARE 2 ││
  5. ┌─────────────┐││
  6. MIDDLEWARE 3 │││
  7. ┌─────────┐ │││
  8. REQUEST YOUR │││ RESPONSE
  9. ──────┼─┼─┼─▷ HANDLER ○─┼┼┼───▷
  10. └─────────┘ │││
  11. └─────────────┘││
  12. └────────────────┘│
  13. └───────────────────┘

使用中间件

NewGRPCServerNewHTTPServer中通过ServerOption进行注册。 如

  1. // http
  2. // 定义opts
  3. var opts = []http.ServerOption{
  4. http.Middleware(
  5. recovery.Recovery(), // 把middleware按照需要的顺序加入
  6. tracing.Server(),
  7. logging.Server(),
  8. ),
  9. }
  10. // 创建server
  11. http.NewServer(opts...)
  12. //grpc
  13. var opts = []grpc.ServerOption{
  14. grpc.Middleware(
  15. recovery.Recovery(), // 把middleware按照需要的顺序加入
  16. tracing.Server(),
  17. logging.Server(),
  18. ),
  19. }
  20. // 创建server
  21. grpc.NewServer(opts...)

自定义中间件

需要实现Middleware接口。 中间件中您可以使用tr, ok := transport.FromServerContext(ctx)获得Transporter实例以便访问接口相关的元信息

基本的代码模板

  1. import (
  2. "context"
  3. "github.com/go-kratos/kratos/v2/middleware"
  4. "github.com/go-kratos/kratos/v2/transport"
  5. )
  6. func Middleware1() middleware.Middleware {
  7. return func(handler middleware.Handler) middleware.Handler {
  8. return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
  9. if tr, ok := transport.FromServerContext(ctx); ok {
  10. // Do something on entering
  11. defer func() {
  12. // Do something on exiting
  13. }()
  14. }
  15. return handler(ctx, req)
  16. }
  17. }
  18. }