刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • go-kit

    • 【go-kit教程】go-kit初识
    • 【go-kit教程】go-kit启动http服务
    • 【go-kit教程】go-kit集成gin启动服务
    • 【go-kit教程】go-kit集成grpc和protobuf
    • 【go-kit教程】go-kit中间件
      • go-kit中间件
      • 日志中间件
        • 1. transport 日志中间件
        • 2. service 中间件
      • 完整示例代码
    • 【go-kit教程】go-kit服务注册发现与负载均衡
    • 【go-kit教程】go-kit限流和熔断
    • 【go-kit教程】go-kit链路追踪
    • 【go-kit教程】go-kit集成Prometheus
  • 微服务
  • go-kit
bigox
2023-02-23
目录

【go-kit教程】go-kit中间件

# go-kit中间件

  • go-kit提供了很多用于构建微服务的组件,包括中间件。中间件是在HTTP请求和响应之间处理请求的一些逻辑,可以用于实现一些通用的功能,例如认证、日志记录、缓存等。

  • 官方中间件定义

    type Middleware func(Endpoint) Endpoint
    
    1
  • 在go-kit中间件可以通过装饰器模式来实现,即在原来的服务之上再加上一层逻辑。Go-Kit中间件通常有三种类型:

    1. 服务(service)中间件:服务中间件是针对服务层面的中间件,可以拦截请求,修改上下文信息,添加一些必要的头信息,以及添加跨域资源共享(CORS)等。

    2. 传输(transport )中间件:传输中间件是针对传输层面的中间件,例如负载均衡器和熔断器等。

    3. enpoint中间件:endpoint 中间件的一种常见方式是使用装饰器模式。可以定义一个函数,该函数接受一个 endpoint 作为参数,返回一个新的 endpoint,该新 endpoint 可以在原始 endpoint 被调用前或后添加一些逻辑。例如:

      func MiddlewareOne(next endpoint.Endpoint) endpoint.Endpoint {
          return func(ctx context.Context, request interface{}) (interface{}, error) {
              // 在原始 endpoint 被调用前添加逻辑
              // ...
              // 调用原始 endpoint
              response, err := next(ctx, request)
              // 在原始 endpoint 被调用后添加逻辑
              // ...
              return response, err
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
  • go-kit提供了一些默认的中间件,例如Logging中间件,它可以记录每个请求的日志信息,包括请求的URL、方法、请求体、响应码和响应体等。还有一些其他的中间件,例如Circuit Breaker中间件、Rate Limiter中间件等。

# 日志中间件

# 1. transport 日志中间件

  • 中间件定义

    func LoggingMiddleware(logger log.Logger) endpoint.Middleware {
        return func(next endpoint.Endpoint) endpoint.Endpoint {
            return func(ctx context.Context, request interface{}) (interface{}, error) {
                logger.Log("msg", "starting request")
    
                // 计算请求处理时间
                start := time.Now()
                defer func() {
                    logger.Log("msg", "finished request", "took", time.Since(start))
                }()
    
                // 调用下一个 endpoint
                response, err := next(ctx, request)
                if err != nil {
                    logger.Log("msg", "request failed", "err", err)
                    return nil, err
                }
    
                logger.Log("msg", "request succeeded")
                return response, nil
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
  • 项目引用实例

    /**
     * @date: 2023/2/22
     * @desc:
     */
    
    package transports
    
    import (
    	"context"
    	"github.com/go-kit/kit/log"
    	grpctranspoint "github.com/go-kit/kit/transport/grpc"
    	"my-kit-demo/endpoints"
    	"my-kit-demo/middlewares"
    	"my-kit-demo/proto"
    )
    
    type pingGRPCServer struct {
    	sayPing grpctranspoint.Handler
    	proto.UnimplementedPingServer
    }
    
    func (s *pingGRPCServer) SayPing(ctx context.Context, req *proto.ReqMsg) (*proto.ResMsg, error) {
    	_, resp, err := s.sayPing.ServeGRPC(ctx, req)
    	if err != nil {
    		return nil, err
    	}
    	return resp.(*proto.ResMsg), nil
    }
    
    func NewPingGRPCServer(ept endpoints.PingEndpoint, logger log.Logger) proto.PingServer {
    	options := []grpctranspoint.ServerOption{}
    	newEndpoint := middlewares.LoggingMiddleware(logger)(ept.SayPing)  // 引入日志中间件
    	return &pingGRPCServer{
    		sayPing: grpctranspoint.NewServer(
    			newEndpoint,
    			decodeGRPCPingRequest,
    			encodeGRPCPingResponse,
    			options...,
    		),
    	}
    }
    
    func decodeGRPCPingRequest(_ context.Context, request interface{}) (interface{}, error) {
    	req := request.(*proto.ReqMsg)
    	return &proto.ReqMsg{Msg: req.Msg}, nil
    }
    
    func encodeGRPCPingResponse(_ context.Context, response interface{}) (interface{}, error) {
    	res := response.(*proto.ResMsg)
    	return &proto.ResMsg{Msg: res.Msg}, nil
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52

# 2. service 中间件

service 中间件要为每一个service创建一个中间件,因为中间件要重写我们定义service接口的方法

  • 中间件定义

    func LoggingMiddleware(logger log.Logger) ServiceMiddleware {
        return func(next MyService) MyService {
            return loggingMiddleware{logger, next}
        }
    }
    
    type loggingMiddleware struct {
        logger log.Logger
        next   MyService
    }
    
    func (mw loggingMiddleware) MyMethod(ctx context.Context, req Request) (resp Response, err error) {
        defer func(start time.Time) {
            mw.logger.Log(
                "method", "MyMethod",
                "input", req,
                "output", resp,
                "err", err,
                "took", time.Since(start),
            )
        }(time.Now())
    
        // 调用下一个方法
        return mw.next.MyMethod(ctx, req)
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
  • 项目引用

    /**
     * @date: 2023/2/22
     * @desc:
     */
    
    package middlewares
    
    import (
    	"context"
    	"github.com/go-kit/kit/log"
    	"my-kit-demo/services"
    	"time"
    )
    
    func LoggingPingServiceMiddleware(logger log.Logger) func(services.PingService) services.PingService {
    	return func(next services.PingService) services.PingService {
    		return loggingMiddleware{logger, next}
    	}
    }
    
    type loggingMiddleware struct {
    	logger log.Logger
    	next   services.PingService
    }
    
    func (lm loggingMiddleware) SayPing(ctx context.Context, req string) (resp string, err error) {
    	defer func(start time.Time) {
    		lm.logger.Log(
    			"method", "PingService",
    			"input", req,
    			"output", resp,
    			"err", err,
    			"took", time.Since(start),
    		)
    	}(time.Now())
    
    	// 调用下一个方法
    	return lm.next.SayPing(ctx, req)
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40

# 完整示例代码

  • https://github.com/hellolib/go-kit-demo/tree/main/my-kit-demo
#Go
上次更新: 2023/04/16, 18:35:33
【go-kit教程】go-kit集成grpc和protobuf
【go-kit教程】go-kit服务注册发现与负载均衡

← 【go-kit教程】go-kit集成grpc和protobuf 【go-kit教程】go-kit服务注册发现与负载均衡→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式