kong網關反向代理grpc請求
kong網關轉發http服務,各大博主都已經聊包漿了。
kong網關原生支持代理gRPC請求,本文通過一個示例來記錄通過kong網關管理gRPC服務,并且使用grpcbin和grpcurl哼哈二將來模擬和驗證grpc服務能力。
kong網關核心的控制面實體:
- service : 上游服務的抽象
- route : 客戶端請求被分流的規則
- upstream (+ target): 支持負載均衡、健康檢查
- consumer: 用于標識使用API服務的外部客戶端, 一般需要結合plugins來識別
我們首先忽略網關,搭建一個grpc點對點服務調用。
1. grpc點對點
grpc 是基于http2的高性能rpc框架,根據http2是否啟用TLS演化出grpc和grpcs
docker run -it -d --rm -p 9000:9000 -p 9001:9001 moul/grpcbin
啟動了grpc服務,占用端口9000和9001:
2025/10/21 06:21:09 listening on :9000 (insecure gRPC)
2025/10/21 06:21:09 listening on :9001 (secure gRPC + secure HTTP/2)
安裝grpcurl,訪問grpc服務:
grpcurl -v -d '{"greeting": "Kong!"}' \
-plaintext localhost:9000 hello.HelloService.SayHello
或
grpcurl -v -d '{"greeting": "Kong!"}' \
-insecure localhost:9001 hello.HelloService.SayHello
參數解釋如下:
- plaintext: Use plain-text HTTP/2 when connecting to server (no TLS)
- insecure: Skip server certificate and domain verification. (NOT SECURE!) Not
valid with -plaintext option.
grpcurl -v -d '{"greeting":"kong!"}'
-plaintext localhost:9000 hello.HelloService.SayHello, grpc點對點的結果如下:

1.1 grpcurl 工作原理
grpc 是基于http2的高性能rpc框架(protobuffer是打解包協議),框架屏蔽了底層打解包和通信細節, 使調用者像調用本地函數一樣遠程調用。
grpcurl 將對人類友好的json格式參數轉換成pb協議并傳輸, grpcurl必須了解服務的protobuffer協議(服務的schema)
- 使用grpc的服務反射協議: 注冊了一個服務(列出服務器上注冊的grpc服務和方法), 各大語言都提供這一能力
- protobuffer.proto 源文件
- protoSets proto文件編譯后產生的stub文件
本次grpcbin示例服務已經實現了服務反射協議, 產生的grpc.reflection.v1alpha.ServerReflectiongrpc服務 提供了暴露grpc服務元信息的能力。
listener, err := net.Listen("tcp", *insecureAddr)
if err != nil {
log.Fatalf("failted to listen: %v", err)
}
// create gRPC server
s := grpc.NewServer()
grpcbinpb.RegisterGRPCBinServer(s, &grpcbinhandler.Handler{})
hellopb.RegisterHelloServiceServer(s, &hellohandler.Handler{})
addsvcpb.RegisterAddServer(s, &addsvchandler.Handler{})
abepb.RegisterABitOfEverythingServiceServer(s, abehandler.NewHandler())
// register reflection service on gRPC server
reflection.Register(s)
// serve
log.Printf("listening on %s (insecure gRPC)\n", *insecureAddr)
if err := s.Serve(listener); err != nil {
log.Fatalf("failed to serve: %v", err)
}
我們使用grpcurl -plaintext localhost:9000 list 就能看到 目標服務上注冊的所有grpc服務,進一步的使用describe 參數可進一步探究函數和類型信息。

實際上, 本次grpcurl在發出實際grpc請求時,會重度使用到grpc服務反射協議, 我們稍后通過kong網關來觀測。
2. kong gateway腳手架代理grpc請求
grpc是基于http2的高性能rpc框架,本次須確保存在http2代理偵聽器。
kong github給出的docker-kong腳手架開放了8000-8002端口的服務, 但是無http2偵聽器。

核心配置由配置proxy-listen或者變量變量KONG_PROXY_LISTEN決定。
http2: 允許客戶端打開與Kong網關的HTTP2連接。
ssl: 要求通過該地址/端口進行的所有連接都必須啟用TLS。
本次修改成: ${KONG_PROXY_LISTEN:-0.0.0.0:8000 http2,0.0.0.0:8443 ssl http2}
本例kong作為grpc代理服務器,可通過kong-manager或者admin-api建立grpc service 和grpc route。
-
建立服務:

-
建立網關路由
上面列出的grpc服務方法: hello.HelloService.SayHello, 網關要求Path上以/或者~開頭,本次我們先設置成根目錄/:抓取所有的grpc請求。
grpc請求走kong網關反向代理的結果:

上圖清楚的顯示: grpcurl發出的grpc請求,會產生3個grpc調用, 前后兩次目測是通過反射信息 組包和解包,
核心的hello.HelloService.SayHellogrpc調用, 在網關上被解析成/hello.HelloService/SayHello, 也就是/包名.服務名/接口名。
grpc 使用的http2協議,設置為POST請求方法, grpc具體產生的http協議, 請參考:https://grpc.github.io/grpc/core/md_doc__p_r_o_t_o_c_o_l-_h_t_t_p2.html
基于這個原理,可以在網關代理grpc請求的時候,設置更精細的路由path:

[1] grpcurl: http://www.rzrgm.cn/binHome/p/13068129.html
[2] grpc over http2: https://grpc.github.io/grpc/core/md_doc__p_r_o_t_o_c_o_l-_h_t_t_p2.html
[3] docker-kong腳手架: https://github.com/Kong/docker-kong
[4] proxy-listen: https://developer.konghq.com/gateway/configuration/#proxy-listen
本文來自博客園,作者:{有態度的馬甲},轉載請注明原文鏈接:http://www.rzrgm.cn/JulianHuang/p/19156662
歡迎關注我的原創技術、職場公眾號, 加好友談天說地,一起進化

浙公網安備 33010602011771號