使用ESPv2做HTTP转gRPC的Google Cloud Run微服务通信问题
问题分析与解决方案
第一个错误:unknown service .
这个错误的核心原因是你在api_config.yaml的apis字段中引用了一个不存在的gRPC服务package.MyAPIGateway。ESPv2需要明确知道要转码的gRPC服务元数据,而你并没有在任何地方注册这个服务——你的User服务注册的是userpb.UserService,API Gateway本身不需要代码,但它必须依赖真实存在的gRPC服务定义来完成HTTP转gRPC的映射。
你需要把api_config.yaml中的apis字段修改为指向实际存在的userpb.UserService,同时调整所有相关的selector路径,让ESPv2明确关联User服务的gRPC接口。
第二个错误:503上游连接失败
修改配置后出现的503错误,通常是ESPv2无法正常连接到User服务导致的,常见原因及解决方法如下:
1. Cloud Run服务权限问题
Cloud Run默认要求调用者身份验证,ESPv2所在的服务账号没有权限访问User服务。解决方法:
- 找到ESPv2服务使用的服务账号(默认是
service-<项目编号>@serverless-robot-prod.iam.gserviceaccount.com)。 - 进入User服务的Cloud Run权限设置页面,添加该服务账号,并赋予Cloud Run Invoker角色。
- 测试环境下可临时将User服务设置为允许未认证调用(生产环境不建议),验证是否为权限问题。
2. 服务地址与端口配置错误
确保backend.rules中的address配置正确:
- 必须使用
grpcs://协议,因为Cloud Run的gRPC服务默认使用TLS加密。 - 地址必须是User服务的完整域名(比如
user-service.a.run.app),且服务处于运行状态。 - 确认User服务的Go代码监听
8080端口(Cloud Run默认将请求转发到这个端口),代码示例:lis, err := net.Listen("tcp", ":8080") if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer.Serve(lis)
3. ESPv2未加载正确的gRPC服务元数据
ESPv2需要知道User服务的gRPC方法签名才能完成转码,你需要确保部署ESPv2时:
- 正确引用了User服务的
.proto文件,或者通过protoc生成了包含服务定义的配置文件。 api_config.yaml中的apis字段准确指向userpb.UserService(与proto文件中的定义一致)。
修正后的完整api_config.yaml示例
type: google.api.Service config_version: 3 name: <你的ESP服务URL>.a.run.app title: My Microservices apis: - name: userpb.UserService usage: rules: - selector: userpb.UserService.* allow_unregistered_calls: true backend: rules: - selector: userpb.UserService.GetUser address: grpcs://user-service.a.run.app http: rules: - selector: userpb.UserService.GetUser get: /user
额外排查步骤
- 使用
grpcurl工具直接调用User服务的gRPC接口,确认服务本身正常:grpcurl -d '{"user_id": "123"}' user-service.a.run.app:443 userpb.UserService.GetUser - 查看ESPv2的日志,获取更详细的连接失败原因,比如TLS握手错误、DNS解析失败等。
内容的提问来源于stack exchange,提问作者MikeBird
相关产品推荐
相关产品推荐

