ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

APISIX gRPC Proxy 实战指南:用 HTTP/2 透明代理 gRPC/gRPCS 流量

2026/9/14 9:44:43 拓冰建站 浏览量
APISIX gRPC Proxy 实战指南:用 HTTP/2 透明代理 gRPC/gRPCS 流量 APISIX gRPC Proxy 实战指南用 HTTP/2 透明代理 gRPC/gRPCS 流量【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix导读本文基于 Apache APISIX 官方文档中的 gRPC Proxy 章节系统讲解如何在 APISIX 中创建 gRPC 代理路由把来自 gRPC 客户端的请求转发到后端的 gRPC/gRPCS 服务。你将掌握grpc与grpcs两种上游scheme的配置差异、TLS 加密与明文 HTTP/2 两种暴露方式的开启方法以及用grpcurl验证代理是否生效的完整流程。全文以 docs/en/latest/grpc-proxy.md 为骨架并结合仓库源码apisix/init.lua、apisix/upstream.lua、apisix/cli/ngx_tpl.lua 等说明底层实现原理。gRPC 代理的核心链路APISIX 对 gRPC 的代理本质上是一条透传链路gRPC client - APISIX - gRPC/gRPCS server客户端与 APISIX 之间走 HTTP/2可以是 TLS 加密的 HTTP/2也可以是明文 HTTP/2APISIX 根据路由配置把请求转发到后端的 gRPC 或 gRPCS 服务。由于 gRPC 本身构建在 HTTP/2 之上APISIX 在这一场景下实际扮演的是 HTTP/2 反向代理的角色不需要对 gRPC 帧做编解码——这也是它能获得较高转发性能的原因。核心参数配置 gRPC 代理路由时只需要关注两个关键字段scheme路由 upstream 的协议必须是grpc明文转发到 gRPC 服务或grpcs转发到自建 TLS 的 gRPC 服务。uri格式为/service/method例如/helloworld.Greeter/SayHello即包名.服务名/方法名的完整 gRPC 方法路径。从源码看 scheme 的合法取值在 apisix/schema_def.lua 中upstream 的scheme字段定义如下scheme { default http, enum {grpc, grpcs, http, https, tcp, tls, udp, kafka}, description The scheme of the upstream. .. For L7 proxy, it can be one of grpc/grpcs/http/https. .. For L4 proxy, it can be one of tcp/tls/udp. .. For specific protocols, it can be kafka. },可以看到grpc与grpcs是 L7 代理七层代理合法取值的一部分默认值为http。如果忘记把scheme改为grpc/grpcs路由会按普通 HTTP 上游处理无法正确完成 gRPC 转发。创建 gRPC 代理路由准备 admin_key以下命令从config.yaml中读取 Admin API 的密钥并保存到环境变量后续的 curl 请求都需要通过X-API-KEY请求头携带该密钥admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g)创建路由通过 Admin API 创建一个代理 gRPC 服务的路由curl http://127.0.0.1:9180/apisix/admin/routes/1 -H X-API-KEY: $admin_key -X PUT -d { methods: [POST, GET], uri: /helloworld.Greeter/SayHello, upstream: { scheme: grpc, type: roundrobin, nodes: { 127.0.0.1:50051: 1 } } }配置要点uri必须精确匹配 gRPC 方法路径/helloworld.Greeter/SayHello对应helloworld.proto中Greeter服务的SayHello方法。methods可显式声明gRPC 请求在 HTTP/2 上以 POST 语义发送示例中同时放开了POST与GET以便测试。upstream.scheme必须为grpc这是本示例与普通 HTTP 路由唯一的本质区别。nodes指向 gRPC 服务地址127.0.0.1:50051是本地 gRPC 服务的监听地址type: roundrobin表示轮询负载均衡。三个必须注意的前提upstream 的scheme必须是grpc或grpcs否则不进入 gRPC 转发逻辑。APISIX 默认使用 TLS 加密的 HTTP/2 对外暴露 gRPC 服务因此需要先配置 SSL 证书即配置 9443 端口对应的证书。APISIX 也支持用明文 HTTP/2 暴露 gRPC 服务不依赖 TLS通常用于内网环境代理 gRPC 服务配置方法见下文明文 HTTP/2小节。源码层面的转发证据在 apisix/init.lua 的 HTTP access 阶段APISIX 会根据上游协议选择转发目标local up_scheme api_ctx.upstream_scheme if up_scheme grpcs or up_scheme grpc then stash_ngx_ctx() return ngx.exec(grpc_pass) end即只要上游 scheme 是grpc或grpcs请求就会被内部跳转到名为grpc_pass的 nginx location。该 location 定义在 apisix/cli/ngx_tpl.lua 中location grpc_pass { access_by_lua_block { apisix.grpc_access_phase() } grpc_set_header :authority $upstream_host; grpc_set_header Content-Type application/grpc; grpc_set_header TE trailers; grpc_socket_keepalive on; grpc_pass $upstream_scheme://apisix_backend; ... }这里的关键是grpc_pass $upstream_scheme://apisix_backend;其中$upstream_scheme正是从路由 upstream 的scheme字段解析出来的变量最终驱动 nginx 的 grpc 模块完成对后端 gRPC 服务的转发。同时grpc_access_phase对应 apisix/init.lua负责在转发前设置必要的上游参数。测试 TLS 加密的 HTTP/2 转发默认方式APISIX 默认在9443端口监听 TLS 加密的 HTTP/2。证书配置完成后用grpcurl调用之前创建的路由$ grpcurl -insecure -import-path /pathtoprotos -proto helloworld.proto -d {name:apisix} 127.0.0.1:9443 helloworld.Greeter.SayHello { message: Hello apisix }返回{message: Hello apisix}即表示代理链路已打通。grpcurl是一个类似 curl 的 gRPC 客户端命令行工具用于与 gRPC 服务交互可参照其官方文档安装。命令参数说明-insecure跳过对 APISIX 服务端证书的校验测试环境使用生产环境应替换为受信任证书。-import-path /pathtoprotos指定.proto文件的导入路径请替换为helloworld.proto实际所在目录。-proto helloworld.proto指定描述服务方法的 proto 文件。-d {name:apisix}请求消息体JSON 形式grpcurl 会按 proto 定义编码。127.0.0.1:9443APISIX 的 TLS HTTP/2 监听地址。helloworld.Greeter.SayHello要调用的完整方法名。开启明文 HTTP/2 并测试默认情况下 APISIX 只为 TLS 加密的 HTTP/2 监听9443端口。如需在内网以明文 HTTP/2 暴露 gRPC 服务可以在conf/config.yaml的apisix段配置node_listen与enable_http2apisix: node_listen: - port: 9080 - port: 9081 enable_http2: truenode_listenAPISIX 的 HTTP 监听端口列表此处新增9081作为明文 HTTP/2 监听端口默认的9080依然保留。enable_http2: true开启 HTTP/2 支持。参考 conf/config.yaml.example 中的默认配置该选项默认即为开启状态node_listen的完整写法含ip字段可参见 conf/config.yaml.example。修改配置后重启 APISIX再用grpcurl以明文方式调用$ grpcurl -plaintext -import-path /pathtoprotos -proto helloworld.proto -d {name:apisix} 127.0.0.1:9081 helloworld.Greeter.SayHello { message: Hello apisix }-plaintext表示不使用 TLS。返回正确结果即说明明文 HTTP/2 转发正常工作此时 APISIX 与客户端之间的通信不依赖证书适合纯内网环境。gRPCS代理自带 TLS 的后端 gRPC 服务如果后端 gRPC 服务自身启用了 TLS即所谓的 gRPCSgRPC TLS则需将scheme改为grpcs。以下示例假设 gRPCS 服务运行在50052端口curl http://127.0.0.1:9180/apisix/admin/routes/1 -H X-API-KEY: $admin_key -X PUT -d { methods: [POST, GET], uri: /helloworld.Greeter/SayHello, upstream: { scheme: grpcs, type: roundrobin, nodes: { 127.0.0.1:50052: 1 } } }从源码理解 grpcs 的证书处理当scheme为grpcs时APISIX 与后端之间同样需要建立 TLS 连接。在 apisix/upstream.lua 中可以看到 grpcs 与普通 TLS 上游的参数处理逻辑if scheme grpcs then api_ctx.upstream_grpcs_cert cert api_ctx.upstream_grpcs_key key else local ok, err set_upstream_tls_client_param(cert, key) ... end以及function _M.set_grpcs_upstream_param(ctx) if ctx.upstream_grpcs_cert then local cert ctx.upstream_grpcs_cert local key ctx.upstream_grpcs_key local ok, err set_upstream_tls_client_param(cert, key) if not ok then return 503, err end end end这说明gRPCS 场景下如果路由/上游配置了客户端证书mTLSAPISIX 会先暂存证书并在grpc_access_phase见 apisix/init.lua 中调用set_grpcs_upstream_param阶段将其设置到与后端建立的 TLS 连接上若设置失败则返回 503。也就是说代理grpcs后端时APISIX 既能以 TLS 方式访问后端也支持通过配置向 gRPC 后端提供客户端证书完成双向认证。grpcs 的默认端口行为从测试用例 t/node/grpc-proxy.t 可以看到当 upstream 节点未显式携带端口时grpcsscheme 会默认使用443端口对应 nginx grpc 模块对grpcs://的默认端口约定例如scheme: grpcs且节点为127.0.0.1时实际上游地址解析为grpcs://127.0.0.1:443。因此在生产配置中建议像上文示例一样显式写出端口避免歧义。验证代理链路测试用例参考仓库中已有完整的 gRPC 代理测试覆盖可作为排障与理解行为的参考。例如 t/node/grpc-proxy.t 中的用例使用与本文完全一致的方式验证grpcurl -import-path ./t/grpc_server_example/proto -proto helloworld.proto -plaintext -d {name:apisix} 127.0.0.1:1984 helloworld.Greeter.SayHello测试用的helloworld.proto等示例文件位于 t/grpc_server_example/protogRPC 服务端示例的完整工程可参考仓库中的 t/grpc_server_example。当你本地搭建验证环境时可以复用这一套 proto 定义与服务端代码。常见问题与排查思路uri不匹配导致 404gRPC 方法路径必须与 proto 中定义的包名.服务名/方法名完全一致例如/helloworld.Greeter/SayHello。路径写错时 APISIX 无法匹配到路由。scheme忘记改为grpc/grpcs上游会按默认的http处理不会进入grpc_pass转发分支参考 apisix/init.lua。TLS 加密方式下证书未配置默认暴露方式依赖 9443 端口的 SSL 证书请先完成证书配置。内网不想用 TLS按上文明文 HTTP/2小节在conf/config.yaml增加node_listen端口并确保enable_http2: true用grpcurl -plaintext访问对应端口。grpcs后端端口不对grpcs未显式写端口时默认使用443建议始终显式声明端口参考测试用例 t/node/grpc-proxy.t。mTLS 证书设置失败当为 gRPCS 上游配置客户端证书但设置失败时APISIX 会返回 503对应 apisix/upstream.lua 的实现。小结通过本文你已经可以完成 APISIX 上 gRPC 代理的完整闭环用scheme: grpc/scheme: grpcs与/service/method形式的uri创建代理路由通过默认的 TLS 加密 HTTP/29443或显式开启的明文 HTTP/2 两种方式对外暴露 gRPC 服务使用grpcurl -insecure/grpcurl -plaintext分别验证两种链路在源码层面理解grpc_passlocation、$upstream_scheme变量与set_grpcs_upstream_param的作用为后续排障和二次开发打好基础。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考