最近需要使用 apisix 来代理 gRPC 服务, 本文记录一下 apisix 代理 gRPC 服务以及实践过程中遇到的一些问题。

准备

在接下来的步骤前,我们需要准备一个 gRPC 服务,我们使用 kratos 简单启动一个 gRPC 服务:

$ kratos new hellowrold
$ cd helloworld
$ kratos run

一个简单的 gRPC 服务就启动了,我们先直接请求 gRPC 服务看看,通过 postman 请求接口后,接口顺利返回相应的值。

img.png

接下来我们开始本篇的主要内容: apisix 代理服务。

apisix 代理 gRPC 服务

我们使用apisix admin 接口创建 Route: upstream 的 scheme 指定为 grpc 或 grpcs,nodes指定需要代理的服务地址。

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["POST", "GET"],
    "uri": "/helloworld.v1.Greeter/SayHello",
    "upstream": {
        "scheme": "grpc",
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:9001": 1
        }
    }
}'

img_1.png

我们再通过 postman 请求代理后的服务,发现请求错误,错误信息如下:Received RST_STREAM with code 2 triggered by internal client error: Protocol error,根据错误信息得知是协议不兼容的原因,apisix 没有开启 HTTP2支持,我们尝试另外一种方法来添加代理。

我们修改 apisix 的配置文件:

apisix:
    node_listen:
        - port: 9080
          enable_http2: false
        - port: 9081
          enable_http2: true

修改后再次请求接口,gRPC 正确响应返回。

如果你的 gRPC 服务使用了自己的 TLS 加密,即所谓的 gPRCS (gRPC + TLS),那么需要修改 scheme 为 grpcs,并可能需要配置相应的证书。

参考