Skip to main content

使用 Apache APISIX 代理 gRPC 服务

· 阅读需约 6 分钟
喻柏仲
苏钰

本文为大家介绍如何在 Apache APISIX 中通过 grpc-transcode插件来将客户端的 HTTP 流量代理到后端 gRPC 服务上。

项目介绍

Apache APISIX

Apache APISIX 是一个动态、实时、高性能的 API 网关,提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。Apache APISIX 不仅支持插件动态变更和热插拔,而且拥有众多丰富的插件资源库。

gRPC

gRPC 是 Google 发起的一个开源远程过程调用(Remote procedure call)系统。该系统基于 HTTP/2 协议传输,使用 Protocol Buffers 作为接口描述语言,可以在任何环境中运行。通过 gRPC 服务可对负载均衡、链路追踪、健康检查和身份认证等功能进行可插拔模式支持,有效地连接数据中心之间的多项服务。

插件介绍

为了增加对 gRPC 服务代理的支持,Apache APISIX 发布了基于 gRPC 的插件 grpc-transcode,通过 RESTful 方式调用 gRPC 服务。

该插件支持在 Apache APISIX 中指定 .proto 文件的内容,并通过用户自定义 gRPC 服务来实现不同 gRPC 服务的代理。

集成原理

用户在 Apache APISIX 中指定 .proto 内容,通过在 grpc-transcode 插件中的 proto_id 绑定相应的 proto,并配置 .proto 中定义的 Service 和 Method,即可实现 gRPC 服务的代理。

基本原理如下:用户可以在路由中配置一个 grpc-transcode 插件,当路由匹配到请求时,会转发 gRPC 请求到上游的服务中。

note

grpc-transcode 插件支持对 proto_idgrpc service namegrpc service methodgrpc deadline 以及 pb_option 进行配置。基于配置调用上游的 gRPC 服务,并将从上游 gRPC 服务中获取到的响应内容返回至客户端。

如何使用

环境准备

在配置 Apache APISIX 之前,需要先启动 gRPC 服务。

步骤一:配置 grpc-server-example 服务

  1. 克隆 grpc-server-example 仓库。
git clone https://github.com/api7/grpc_server_example
  1. 启动 grpc-server。
cd grpc_server_example
go run main.go
  1. 验证 gRPC 服务,推荐使用 grpcurl 来验证服务的可用性。
grpcurl -d '{"name": "zhangsan"}' -plaintext 127.0.0.1:50051 helloworld.Greeter.SayHello

正确启动 gRPC 服务后,执行上述命令将会输出以下内容。

{
"message": "Hello zhangsan"
}

步骤二:配置 Apache APISIX

  1. 添加 proto
curl http://127.0.0.1:9080/apisix/admin/proto/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"content" : "syntax = \"proto3\";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}"
}'
  1. 在指定 Route 中,代理 gRPC 服务接口。
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/grpctest",
"plugins": {
"grpc-transcode": {
"proto_id": "1",
"service": "helloworld.Greeter",
"method": "SayHello"
}
},
"upstream": {
"scheme": "grpc",
"type": "roundrobin",
"nodes": {
"127.0.0.1:50051": 1
}
}
}'

具体代码释义与支持的参数详情可参考下方:

名称类型存在默认值描述
proto_idstring/integer必须N/A.proto 内容的 id
servicestring必须N/AgRPC 服务名
methodstring必须N/AgRPC 服务中要调用的方法名
deadlinenumber可选0gRPC 服务截止时间
pb_optionarray[string(pb_option_def)]可选N/Aproto 编码过程中的转换选项

测试请求

下面我们将使用 cURL 进行测试。

curl -i http://127.0.0.1:9080/grpctest\?name=world
HTTP/1.1 200 OK
Date: Mon, 27 Dec 2021 06:24:47 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.11.0
Trailer: grpc-status
Trailer: grpc-message

{"message":"Hello world"}
grpc-status: 0
grpc-message:

通过代码反馈可知,已成功将请求代理到后端 gRPC 服务上。

关闭插件

如使用完毕,只需要移除路由配置里 plugin 相关的配置,即可关闭路由上的 grpc-transcode 插件。得益于 Apache APISIX 插件热加载模式,开启和关闭都无需重启 Apache APISIX。

# 关闭插件
curl http://127.0.0.1:9080/apisix/admin/routes/111 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/grpctest",
"plugins": {},
"upstream": {
"scheme": "grpc",
"type": "roundrobin",
"nodes": {
"127.0.0.1:50051": 1
}
}
}'

总结

本文为大家介绍了关于 grpc-transcode 插件的使用步骤,通过 RESTful 将请求代理到后端 gRPC 服务上。通过使用该插件,Apache APISIX 仅需通过配置即可实现对 gRPC 服务的代理。

更多关于 grpc-transcode 插件的说明和完整配置列表,请参考官方文档