使用go语言实现一个grpc拦截器

描述

在开发grpc服务时,我们经常会遇到一些通用的需求,比如:日志、链路追踪、鉴权等。这些需求可以通过grpc拦截器来实现。本文使用go语言来实现一个 grpc一元模式(Unary)拦截器,上报链路追踪信息。

原始类型定义

我们可以在grpc的源码包里(interceptor.go),找到一元模式拦截器的类型定义:

 

 

// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
// of the service method implementation. It is the responsibility of the interceptor to invoke handler
// to complete the RPC.
type UnaryServerInterceptor func(ctx context.Context, req any, info *UnaryServerInfo, handler UnaryHandler) (resp any, err error)

 

 

从上面的定义可以看出,一元模式拦截器是一个函数,接收四个参数,返回两个参数。下面我们来看一下这四个参数的含义:

ctx:上下文对象。

req:请求参数

info:包含了RPC的元信息,比如服务名、方法名等。

handler 实例的方法,用来调用实际的RPC方法。

我们只需要实现一个上述类型的函数,在里面实现我们的功能,然后再执行handler函数,就可以实现一个拦截器了。

实现拦截器

我们新建一个项目grpcdemo。

服务定义

我们先在项目目录下新建一个proto文件,定义一个服务:

hello.proto

定义一个Makefile:

 

 

protos:
  protoc --proto_path=./ --go_out=pb --go-grpc_out=pb --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative ./*.proto
tidy:
  go mod tidy


run:
  go mod tidy
  go run main.go

 

 

执行以下命令,生成go代码:

 

 


make protos

代码开发

 

 

第一步,新建一个tracing.go,初始化链路追踪器:

tracing.go

第二步,在main.go文件中,添加相关代码:

main.go

在上面的代码中,我们启动了一个grpc服务,监听8091端口。在启动grpc服务前,初始化了链路追踪信息,然后在grpc服务中,使用了自定义的拦截器。在自定义拦截器中,我们上报了链路追踪信息。

启动jaeger服务

具体的启动方式,可以参考官方文档:www.jaegertracing.io/docs/1.26/g…

测试

我们使用goland的grpc插件,来测试一下:

 

 


#
GRPC localhost:8091/pb.HelloService/Hello


{
  "name": "ZhangSan"
}






#
GRPC localhost:8091/pb.HelloService/HelloAgain


{
  "name": "ZhangSan"
}

 

 

测试结果:

日志

我们再打开jaeger的UI,查看链路追踪信息:

日志

可以看到,我们的链路追踪信息已经上报到了jaeger服务。

审核编辑:汤梓红

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分