概览
gRPC-Gateway是gRPC生态的一环,用于对HTTP协议的扩展,是一套高性能、高扩展的开源RPC框架。
因此,要掌握gRPC-Gateway,必须要对gRPC有一定的基础,才能明白它的定位与价值。
方案概览
整个方案分为两个方向:
纵向 - RPC协议调用
三个模块:
- 调用方 - API Client
- HTTP服务 - Reverse Proxy
- gRPC服务 - Your gRPC service
两个协议:
- HTTP - 客户端发起的是HTTP协议,传输到反向代理
- gRPC - 反向代理与gRPC服务之间的协议是gRPC
关键点:
- Reverse Proxy实现了的关键能力是:将HTTP协议转化为gRPC协议
- 可同时提供2个服务:HTTP和gRPC,只是HTTP服务的最终实现还是调用到了gRPC
横向 - Protobuf的代码生成
- gRPC-Gateway部分:自动生成反向代理
- gRPC部分:自动生成stub
stub这个单词很有意思,相对准确的翻译是存根、残端,和面向对象中的 接口 有异曲同工之妙:提供了实现的框架,但具体实现仍交由开发者。
开发工作
对开发者来说,整个方案的工作分为两部分:
- RPC部分 - 编写
proto
文件 - 业务逻辑部分 - 编写gRPC中的
stub
的实现
开发思路
1. RPC开发 - proto文件的编写
我们看一个官方github上的示例proto
文件:
1 | syntax = "proto3"; |
我们从上到下,对里面的语法做简单的分析:
- proto3版本
- proto的包名称
- 生成Go语言代码后的Go Package
- 导入依赖的proto文件
- Message - 表示RPC的数据结构,按规则生成到各语言的代码
- Service - 一组RPC的抽象
- rpc - 一个具体方法,包括 方法名(请求Message) returns (返回Message)
- google.api.http - HTTP协议的定义,如示例中的方法和URL
2. 代码生成
如何将proto文件生成为Go语言的stub
代码,官方提供了两个路径:
- buf(新方式,配置简单,推荐)
- protoc(经典方式,配置较为复杂)
具体的操作方法可以参考: https://github.com/grpc-ecosystem/grpc-gateway#usage 。
3. 业务实现
代码生成的只是一个stub
,具体实现需要我们自己编码。上述方法生成的函数签名大致如下:
1 | func Echo(ctx context.Context, request *proto.StringMessage) returns (response *proto.StringMessage, err error){ |
关于其中的context与error,我在上一讲已经讲过大致的规范。而在gRPC-Gateway中怎么使用呢?我们会在具体示例中再去讲。
4. main函数框架
1~3步骤将一个RPC请求的开发过程串联了起来,作为web服务的高频迭代部分。
但如果要作为一个完整的服务,还需要包括基础的server启动代码,很少需要改动。我们接着看官方的示例代码:
1 | package main |
我们要明确一点:这部分代码并没有包括gRPC服务的启动代码,它已经默认在grpcServerEndpoint
这个地址+端口上启动了。如果没有进程隔离的强要求,我们可以在main
函数中同时启动 gRPC server和gRPC-Gateway server。
gRPC-Gateway启动时有4个重要参数:
- mux,多路复用,功能最为强大,可以添加各种自定义的拦截器等
- grpcServerEndpoint,将HTTP转换成gRPC,再发给gRPC的地址
- opts,服务的启动选项
- :8081,启动地址
关于gRPC部分内容可以参考: https://grpc.io/docs/languages/go/quickstart/
参考示例
整套框架的完整示例可以参考这个文件 - https://github.com/Junedayday/micro_web_service/blob/master/main.go
结论
本篇重点是对gRPC-Gateway最基础的原理和使用进行了分析。
如果你能通过本篇文章,对这个方案有一个基本认识,那么接下来我会带你玩转这个框架。你也无需担心无法实践到日常项目中:gRPC-Gateway中的能力与gin等框架都是共通的,可以轻松地举一反三。
Github: https://github.com/Junedayday/code_reading
Blog: http://junes.tech/
Bilibili: https://space.bilibili.com/293775192
公众号: golangcoding