gRPC Proxy 过滤器(dgp.filter.grpc.proxy)现已支持 gRPC Server Reflection,使得网关能够在不需要预编译 proto 文件的情况下动态解析和检查消息内容。
gRPC Server Reflection 是一项允许 Pixiu 网关在运行时动态发现和解码 gRPC 服务定义的功能。这消除了在网关配置中维护 proto 文件的需要。
执行透明的二进制代理,不解码消息。
使用场景:
配置:
grpc_filters:
- name: dgp.filter.grpc.proxy
config:
reflection_mode: "passthrough" # 或省略(默认值)
使用 gRPC Server Reflection API 动态解码和检查消息内容。
使用场景:
配置:
grpc_filters:
- name: dgp.filter.grpc.proxy
config:
reflection_mode: "reflection"
descriptor_cache_ttl: 300 # 5分钟缓存
先尝试反射,失败时回退到透传模式。
使用场景:
配置:
grpc_filters:
- name: dgp.filter.grpc.proxy
config:
reflection_mode: "hybrid"
reflection_timeout: 5s
static_resources:
listeners:
- name: "grpc-gateway"
protocol_type: "GRPC"
address:
socket_address:
address: "0.0.0.0"
port: 8882
filter_chains:
filters:
- name: dgp.filter.network.grpcconnectionmanager
config:
route_config:
routes:
- match:
prefix: "/echo.EchoService/"
route:
cluster: "echo-grpc"
grpc_filters:
- name: dgp.filter.grpc.proxy
config:
# 反射模式(默认: "passthrough")
reflection_mode: "reflection"
# 方法描述符缓存 TTL(秒)
descriptor_cache_ttl: 300
# 启用 Triple 协议检测
enable_protocol_detection: true
# 混合模式的反射超时
reflection_timeout: 5s
clusters:
- name: "echo-grpc"
lb_policy: "RoundRobin"
endpoints:
- socket_address:
address: 127.0.0.1
port: 50051
protocol_type: "GRPC"
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
reflection_mode | string | "passthrough" | 反射模式: "passthrough"、"reflection" 或 "hybrid" |
descriptor_cache_ttl | int | 300 | 方法描述符缓存 TTL(秒) |
enable_protocol_detection | bool | false | 启用 Triple 协议检测 |
reflection_timeout | string | "5s" | 混合模式下等待反射的最大时间 |
enable_tls | bool | false | 启用后端连接的 TLS |
tls_cert_file | string | "" | TLS 证书文件路径 |
tls_key_file | string | "" | TLS 密钥文件路径 |
keepalive_time | string | "300s" | 后端连接的保活时间 |
keepalive_timeout | string | "5s" | 保活超时时间 |
connect_timeout | string | "5s" | 连接超时时间 |
max_concurrent_streams | uint32 | 0(无限制) | 最大并发流数 |
要使用 reflection 或 hybrid 模式,你的后端 gRPC 服务器必须启用 Server Reflection。
import (
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
func main() {
server := grpc.NewServer()
// 注册你的服务
echo.RegisterEchoServiceServer(server, &echoServer{})
// 启用服务器反射
reflection.Register(server)
// 启动服务器
lis, _ := net.Listen("tcp", ":50051")
server.Serve(lis)
}
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.reflection.v1alpha.ServerReflectionGrpc;
public class EchoServer {
public static void main(String[] args) throws Exception {
Server server = ServerBuilder
.forPort(50051)
.addService(new EchoServiceImpl())
// 启用服务器反射
.addService(ServerReflectionGrpc.newInstance())
.build()
.start();
server.awaitTermination();
}
}
import grpc
from grpc_reflection.v1alpha import reflection
from concurrent import futures
class EchoService(echo_pb2_grpc.EchoServiceServicer):
# ... 实现 ...
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
echo_pb2_grpc.add_EchoServiceServicer_to_server(EchoService(), server)
# 启用服务器反射
reflection.enable_server_reflection(
service_names=[echo.DESCRIPTOR.services_by_name['EchoService'].full_name,
reflection.SERVICE_NAME],
server=server
)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
| 特性 | 透传模式 | 反射模式 | 混合模式 |
|---|---|---|---|
| 性能 | 最佳 | 良好 | 更好 |
| 消息检查 | 否 | 是 | 是(可用时) |
| 需要反射 | 否 | 是 | 可选 |
| 回退支持 | N/A | 否 | 是 |
反射模式使用基于 TTL 的缓存来存储从后端服务器获取的方法描述符。
推荐的 TTL 值:
60(1分钟)300(5分钟)1800(30分钟)Pixiu 支持 Dubbo Triple 协议,这是 Apache Dubbo 社区开发的 gRPC 兼容协议。
启用协议检测:
grpc_filters:
- name: dgp.filter.grpc.proxy
config:
enable_protocol_detection: true
原因: 后端服务器未启用 Server Reflection。
解决方案: 在服务器上启用反射:
reflection.Register(grpcServer)
原因: 反射超时或反射服务不可用。
解决方案:
reflection_timeout 值