之前我们团队在 Go 语言上已经统一使用 gRPC + grpc-gateway 来提供 API 服务,最近为了写一个提供一个用于管理分析任务的接口服务,需要使用 Java 来实现(因为需要访问 HBase/HDFS/Flink等,Java 最方便),而 GRPC Gateway 本身是跟语言无关的,所以我就趁着这次机会尝试了一把,发现效果还挺好的
需要了解的基础Protocol buffers 用来序列化数据的框架
gRPC 基于 Protobuff 的 RPC 框架
grpc-gateway 是一个 protoc 的插件,会读取 gRPC 的 proto 定义,然后生成一个把 RESTful 的 API 转换成 gRPC
grpc-gateway 的一些细节
从原理图可知,通过 grpc-gateway 提供的工具,可以生成一个 gateway, gateway 接收 HTTP 请求, 然后把请求再转换成 gRPC 的请求发给 gRPC Server,从 Server 收到响应之后,再将 gRPC 的响应转换为 HTTP 响应返回给客户端
不论 gRPC Server 是通过何种语言实现的,通过 grpc-gateway 都可以实现 HTTP 的方式来访问接口服务
实现
项目组成
dota2-bristleback-job-mgr,是基于 Java + gRPC 提供 RPC 的接口服务
用到的 grpc mvn 插件是 org.xolstice.maven.plugins.protobuf-maven-plugin(这个插件只支持指定一个目录来生成 protobuf/gRPC 的文件,可以用 com.github.os72.protoc-jar-maven-plugin 来指定多个文件夹)
dota2-bristleback-job-grpc-gateway,dota2-bristleback-job-mgr 的 grpc-gateway 实现
这个部分最主要是需要定义 HTTP API 到 gRPC 请求的映射,然后生成必要的 gateway 代码
type: google.api.Service
config_version: 3
http:
rules:
- selector: example.YourService.Echo
post: /v1/example/echo
body: "*"
启动 grpc-gateway 时,只需要指定 gRPC 服务地址以及 gateway 服务监听的地址即可
小结
通过这次的实践,更加让我坚信 grpc-gateway 的使用是正确的方向,使用 proto 定义接口,gRPC / grpc-gateway 自动生成协议代码,对开发人员来说是其友好的方式
后续
swagger JSON 文件 -> API 文档预览
grpc+gateway 可以生成 swagger JSON 文件,而一般前端都是要API文档的,而对于 后端同学来说,写 API 文档也是个麻烦事
虽说可以通过在线的 Swagger Editor 网站来上传 JSON 文件来查看 API 文档,总是不太 方便
现在我们内部使用的是 gitlab 作为代码托管工具,所以,最好的是,我们在 gitlab 的网页上就能直接预览 swagger JSON 对应的 API 文档
所以,之后会尝试去写个 Chrome 插件,确保在 gitlab 上直接看 gRPC 生成的 swagger JSON 对应的 API 文档
grpc+gateway 项目的自动构建
因为 grpc+gateway 本质是一个 gateway,然后它依赖的也只是 proto 文件以及定义 API 映射的 yaml 文件,整个服务都是可以通过工具来生成的
如果是不熟悉Go的同学来使用 grpc+gateway 的话,会有些障碍
我们团队现在已经使用了 Docker 来部署服务
所以,之后也会尝试去设计一个工具,只需要配置 proto 文件以及 API 定义的 yaml 文件,就可以生成 gateway 的二进制文件,并自动打包成 Docker 镜像提供使用,减少大家的工作量