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.

grpc点对点的结果如下:
image

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 参数可进一步探究函数和类型信息。

image

实际上, 本次grpcurl在发出实际grpc请求时,会重度使用到grpc服务反射协议, 我们稍后通过kong网关来观测。

2. kong gateway脚手架代理grpc请求

grpc是基于http2的高性能rpc框架,本次须确保存在http2代理侦听器

kong github给出的docker-kong脚手架开放了8000-8002端口的服务, 但是无http2侦听器。

image

核心配置由配置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。

  • 建立服务:
    image

  • 建立网关路由
    上面列出的grpc服务方法: hello.HelloService.SayHello, 网关要求Path上以/或者~开头,本次我们先设置成根目录/:抓取所有的grpc请求。

grpc请求走kong网关反向代理的结果:
image

上图清楚的显示: 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:
image


[1] grpcurl: https://www.cnblogs.com/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

posted @ 2025-10-21 23:18  码甲哥不卷  阅读(149)  评论(0)    收藏  举报