Envoy gRPC转REST配置失败:配置文件解析报错求助
Envoy配置修复:gRPC客户端与REST服务通信问题
问题场景
需要通过Envoy实现Java gRPC客户端与Scala REST服务的通信,gRPC请求指向/sample端点,但Envoy启动时配置解析失败。
原配置文件
static_resources: listeners: - name: listener_0 address: socket_address: address: 0.0.0.0 port_value: 8080 filter_chains: - filters: - name: envoy.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager codec_type: auto stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: backend domains: ["*"] routes: - match: { prefix: "/sample" } route: cluster: http4s_server_cluster http_filters: - name: envoy.filters.http.grpc_json_transcoder typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder proto_descriptor: "sample.proto" services: - proto_package: "com.proto" proto_service: "SampleService" json_name: "sample" use_remote_address: false access_log: - name: envoy.access_loggers.stdout typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog clusters: - name: http4s_server_cluster connect_timeout: 0.25s type: strict_dns lb_policy: round_robin http2_protocol_options: {} load_assignment: cluster_name: http4s_server_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 8081 # 假设Scala REST服务运行在该端口
启动错误信息
[source/server/server.cc:997] exiting Unable to parse JSON as proto (INVALID_ARGUMENT: invalid JSON in envoy.config.bootstrap.v3.Bootstrap @ static_resources.listeners[0].filter_chains[0].filters[0].typed_config.<any>.http_filters[0].typed_config.<any>.services[0]: string, near 1:869 (offset 868): unexpected character: '{'; expected '"'): {"static_resources":{"clusters":[{"connect_timeout":"0.25s","http2_protocol_options":{},"lb_policy":"round_robin","name":"http4s_server_cluster","load_assignment":{"cluster_name":"http4s_server_cluster","endpoints":[{"lb_endpoints":[{"endpoint":{"address":{"socket_address":{"address":"127.0.0.1","port_value":8081}}}}]}]},"type":"strict_dns"}],"listeners":[{"name":"listener_0","filter_chains":[{"filters":[{"name":"envoy.http_connection_manager","access_log":[{"name":"envoy.access_loggers.stdout","typed_config":{"@type":"type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog"}}],"use_remote_address":false,"typed_config":{"route_config":{"name":"local_route","virtual_hosts":[{"routes":[{"route":{"cluster":"http4s_server_cluster"},"match":{"prefix":"/sample"}}],"name":"backend","domains":["*"]}]},"http_filters":[{"typed_config":{"services":[{"json_name":"sample","proto_package":"com.proto","proto_service":"SampleService"}],"@type":"type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder","proto_descriptor":"sample.proto"},"name":"envoy.filters.http.grpc_json_transcoder"}],"codec_type":"auto","@type":"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager","stat_prefix":"ingress_http"}}]}],"address":{"socket_address":{"address":"0.0.0.0","port_value":8080}}}]}}
错误原因
services字段格式错误:Envoy v3版本的GrpcJsonTranscoder配置中,services是字符串列表,格式为"包名.服务名",原配置使用了v2版本的对象结构,导致解析失败。- 配置层级错误:
use_remote_address和access_log是HttpConnectionManager的内部配置项,原配置将其放在了envoy.http_connection_managerfilter的根层级,属于位置错误。 - 多余的HTTP/2配置:后端是REST服务,通常使用HTTP/1.1,无需配置
http2_protocol_options。 - Protobuf描述符错误:
proto_descriptor需要指向编译后的二进制描述符文件(如.pb),而非.proto源文件。 - 缺少Router过滤器:Envoy HTTP连接管理器必须以Router过滤器结尾,原配置遗漏后会导致请求无法转发。
修正后的配置文件
static_resources: listeners: - name: listener_0 address: socket_address: address: 0.0.0.0 port_value: 8080 filter_chains: - filters: - name: envoy.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager codec_type: auto stat_prefix: ingress_http use_remote_address: false access_log: - name: envoy.access_loggers.stdout typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog route_config: name: local_route virtual_hosts: - name: backend domains: ["*"] routes: - match: { prefix: "/sample" } route: cluster: http4s_server_cluster http_filters: - name: envoy.filters.http.grpc_json_transcoder typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder # 替换为编译后的Protobuf二进制描述符文件路径 proto_descriptor: "sample.pb" services: - "com.proto.SampleService" # 如需自定义方法的JSON名称映射,可添加以下配置 # mapping: # - grpc_method: "com.proto.SampleService/SampleMethod" # json_name: "sample" - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: http4s_server_cluster connect_timeout: 0.25s type: strict_dns lb_policy: round_robin load_assignment: cluster_name: http4s_server_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 8081 # Scala REST服务的端口
关键修改说明
- 修正
services格式:改为"com.proto.SampleService"字符串形式,符合v3 API规范。 - 调整配置层级:将
use_remote_address和access_log移动到HttpConnectionManager的typed_config内部。 - 移除HTTP/2配置:删除
http2_protocol_options,适配REST服务的HTTP/1.1协议。 - 添加Router过滤器:补充Envoy必须的请求转发过滤器。
- Protobuf描述符处理:先通过
protoc编译生成二进制描述符:protoc --descriptor_set_out=sample.pb --include_imports sample.proto
验证步骤
- 生成Protobuf二进制描述符文件。
- 替换为修正后的配置文件。
- 启动Envoy:
envoy --config-path envoy_bridge.yaml。 - 用Java gRPC客户端调用
localhost:8080/sample,Envoy会自动将gRPC请求转成REST格式转发到Scala服务。
内容的提问来源于stack exchange,提问作者Mukhayyo Tashpulatova
相关产品推荐
相关产品推荐

