什么是gRPC?谷歌开源高性能RPC框架详解
gRPC是谷歌推出的一款开源高性能RPC(远程过程调用)框架,近年来在技术社区备受关注。其核心优势不仅在于跨平台兼容性强、支持多种开发语言,更关键的是选择HTTP/2作为底层传输协议。这一选择并非偶然——HTTP/2具备的二进制分帧、多路复用、服务端推送以及头部压缩等特性,使gRPC在处理大规模数据传输(如视频流)以及微服务架构下大量服务之间的频繁交互时表现尤为出色。
可以说,gRPC天生就是为了应对现代分布式系统中的通信挑战而设计的。
Swagger是什么?API文档工具与OpenAPI规范详解
如果说gRPC是通信的“基础设施”,那么Swagger就是API世界的“用户手册”。它是一套完善的工具集,核心目标是帮助开发者自动生成符合RESTful风格的API文档。业内常说的OpenAPI,本质上就是这套描述标准的规范名称。
需要注意:Swagger规范在3.0版本之后,已正式更名为OpenAPI 3.x。
OpenAPI规范如同一根“纽带”,将Swagger工具与RESTful API设计风格紧密连接,三者共同形成了一套完整的生态闭环。具体而言,OpenAPI负责标准化RESTful API的文档表示,而Swagger工具则简化了文档的生成流程。其最终愿景是通过API定义驱动文档和代码的自动生成,确保服务端实现、接口文档以及客户端SDK三者始终保持一致,从而大幅提升前后端团队的协作效率。
如何将gRPC接口文档转换为Swagger规范
准备工作(先决条件)
gRPC接口的数据交换依赖于轻量级的Protobuf序列化协议,这使得它在资源受限场景下表现更高效。因此,整个转换流程离不开protocol buffer文件(.proto)的支持。
下面以Go语言为例,演示如何将.proto文件编译成.go文件,再进一步输出Swagger规范。整个过程需要多个不同的命令行工具,各自扮演关键角色:
| 工具 | 介绍 |
|---|---|
| protobuf | 编译Protocol Buffer所需的命令行工具 |
| protoc-gen-go | 根据.proto文件生成.go文件 |
| protoc-gen-go-grpc | 生成gRPC相关.go文件 |
| protoc-gen-grpc-gateway | 生成grpc-gateway相关.go文件 |
| protoc-gen-openapiv2 | 生成Swagger界面所需的配置文件 |
仅安装这些命令行工具还不够,你还需要根据需求运行至少4种不同的命令来编译*.proto文件。坦白说,这套流程对新手并不友好,略显复杂。
安装
go get github.com/rookie-ninja/rk-boot
go get github.com/rookie-ninja/rk-grpc
快速开始
1. 创建 api/v1/greeter.proto 文件
syntax = "proto3";
package api.v1;
option go_package = "api/v1/greeter";
service Greeter {
rpc Greeter (GreeterRequest) returns (GreeterResponse) {}
}
message GreeterRequest {
string name = 1;
}
message GreeterResponse {
string message = 1;
}
2. 创建 api/v1/gw_mapping.yaml 文件
type: google.api.Service
config_version: 3
# 请参考 https://github.com/googleapis/googleapis/blob/master/google/api/http.proto 中的 google.api.Http 定义
https:
rules:
- selector: api.v1.Greeter.Greeter
get: /api/v1/greeter
3. 创建 buf.yaml 文件
version: v1beta1
name: github.com/rk-dev/rk-demo
build:
roots:
- api
4. 创建 buf.gen.yaml 文件
version: v1beta1
plugins:
# 需要先安装 protoc-gen-go,根据 proto 文件生成 go 文件
- name: go
out: api/gen
opt: - paths=source_relative
# 需要先安装 protoc-gen-go-grpc,生成 gRPC 相关的 go 文件
- name: go-grpc
out: api/gen
opt:
- paths=source_relative
- require_unimplemented_servers=false
# 需要先安装 protoc-gen-grpc-gateway,生成 grpc-gateway 相关的 go 文件
- name: grpc-gateway
out: api/gen
opt:
- paths=source_relative
- grpc_api_configuration=api/v1/gw_mapping.yaml
# 需要先安装 protoc-gen-openapiv2,根据 proto 文件生成 swagger 配置文件
- name: openapiv2
out: api/gen
opt:
- grpc_api_configuration=api/v1/gw_mapping.yaml
5. 编译 proto 文件
$ buf generate
执行上述命令后,将生成以下文件:
$ tree api/gen
api/gen
└── v1
├── greeter.pb.go
├── greeter.pb.gw.go
├── greeter.swagger.json
└── greeter_grpc.pb.go
1 directory, 4 files
6. 创建 boot.yaml 文件
grpc:
- name: greeter # gRPC 入口名称
port: 8080 # gRPC 入口端口
enabled: true # 启用 gRPC 入口
sw:
enabled: true # 启用 Swagger
jsonPath: "api/gen/v1" # 提供 Swagger 配置文件路径
7. 创建 main.go 文件
package main
import (
"context"
"fmt"
"github.com/rookie-ninja/rk-boot"
"github.com/rookie-ninja/rk-grpc/boot"
"github.com/rookie-ninja/rk-demo/api/gen/v1"
"google.golang.org/grpc"
)
// 应用程序入口
func main() {
// 创建一个新的 boot 实例
boot := rkboot.NewBoot()
// ******
// 注册 gRPC 和 Gateway
// ******
// 获取名为 "greeter" 的 gRPC 入口
grpcEntry := boot.GetEntry("greeter").(*rkgrpc.GrpcEntry)
// 注册 gRPC 注册函数
grpcEntry.AddRegFuncGrpc(registerGreeter)
// 注册 grpc-gateway 注册函数
grpcEntry.AddRegFuncGw(greeter.RegisterGreeterHandlerFromEndpoint)
// 启动
boot.Bootstrap(context.Background())
// 等待关闭信号
boot.WaitForShutdownSig(context.Background())
}
// 实现 [type GrpcRegFunc func(server *grpc.Server)]
func registerGreeter(server *grpc.Server) {
greeter.RegisterGreeterServer(server, &GreeterServer{})
}
// 实现 proto 文件中定义的 gRPC 服务
type GreeterServer struct{}
func (server *GreeterServer) Greeter(ctx context.Context, request *greeter.GreeterRequest) (*greeter.GreeterResponse, error) {
return &greeter.GreeterResponse{
Message: fmt.Sprintf("Hello %s!", request.Name),
}, nil
}
8. 文件夹结构
$ tree
.
├── api
│ ├── gen
│ │ └── v1
│ │ ├── greeter.pb.go
│ │ ├── greeter.pb.gw.go
│ │ ├── greeter.swagger.json
│ │ └── greeter_grpc.pb.go
│ └── v1
│ ├── greeter.proto
│ └── gw_mapping.yaml
├── boot.yaml
├── buf.gen.yaml
├── buf.yaml
├── go.mod
├── go.sum
└── main.go
4 directories, 12 files
9. 验证
启动服务后,可通过以下地址访问Swagger界面:https://localhost:8080/sw
无需复杂流程:用Apifox轻松管理gRPC接口
说实话,上面那一整套配置下来,光是命令行和YAML文件就足够让人头疼。有没有更简便的方法?答案是肯定的。Apifox提供了一种直观的方式来管理gRPC接口,支持中文界面,学习成本极低。
它支持直接基于.proto文件进行gRPC调试,包括一元调用和流式调用。整个流程异常简单:创建项目时选择“gRPC项目”,然后导入.proto文件,无需编写任何代码,即可直接发起调用。
在调试之前,需要先导入作为API定义的.proto文件。如果某个.proto文件依赖了其他文件,还需要手动添加依赖关系目录。
一元调用
在地址栏填写URL后,直接点击“调用”按钮即可。
流式调用
流式调用支持服务端流、客户端流和双向流。发起调用后,你可以在Message标签下编写消息并发送。Apifox提供了一个时间线视图,会按时间顺序集中展示调用状态、已发送的消息和已收到的消息。点击任何一条消息,都可以非常方便地查看其详情。
知识扩展:
- API开发:gRPC还是GraphQL?
- gRPC接口测试方法
