如何在GCP API Gateway中配置多个gRPC Cloud Run后端服务?
在单个GCP API Gateway中配置多个gRPC Cloud Run后端服务
你遇到的问题核心是多个独立生成的.pb描述符文件会互相覆盖同名服务定义,导致API Gateway无法识别第一个服务。下面是两种可行的解决方法:
方法一:给proto文件添加唯一包名(推荐)
如果可以修改proto文件(哪怕只是添加包声明),这是最规范的解决方式:
给每个proto文件添加独立的
package声明,避免服务名冲突:
比如第一个服务的proto:package first; service FirstService { // 服务方法定义 }第二个服务的proto:
package second; service SecondService { // 服务方法定义 }重新生成每个服务的描述符文件:
protoc --descriptor_set_out=first_descriptor.pb --include_imports first_service.proto protoc --descriptor_set_out=second_descriptor.pb --include_imports second_service.proto修改
api_config.yaml,使用完整的服务名称(包名+服务名):apis: - name: first.FirstService - name: second.SecondService backend: rules: - selector: 'first.FirstService.*' address: 'grpcs://first-cloud-run-service-url' - selector: 'second.SecondService.*' address: 'grpcs://second-cloud-run-service-url'重新创建API配置:
gcloud api-gateway api-configs create [你的配置名] \ --api=[你的API名] \ --grpc-files=first_descriptor.pb,second_descriptor.pb,api_config.yaml \ --project=[你的项目ID]
方法二:合并两个proto为一个描述符文件(无需修改proto)
如果完全不想改动proto文件,可以把两个proto合并生成一个描述符文件,避免覆盖:
用protoc同时编译两个proto,生成单个合并的描述符:
protoc --descriptor_set_out=combined_descriptor.pb --include_imports first_service.proto second_service.proto修改
api_config.yaml(保持原来的服务名即可):apis: - name: FirstService - name: SecondService backend: rules: - selector: 'FirstService.*' address: 'grpcs://first-cloud-run-service-url' - selector: 'SecondService.*' address: 'grpcs://second-cloud-run-service-url'重新创建API配置,使用合并后的描述符:
gcloud api-gateway api-configs create [你的配置名] \ --api=[你的API名] \ --grpc-files=combined_descriptor.pb,api_config.yaml \ --project=[你的项目ID]
错误原因说明
当你传入多个独立的.pb描述符文件时,GCP API Gateway的配置工具会按顺序加载这些描述符,后加载的描述符中如果存在与前一个同名的服务(无包名区分时),会直接覆盖前一个的定义,导致第一个服务的元数据丢失,从而出现"无法解析API"和"选择器不匹配"的错误。
内容的提问来源于stack exchange,提问作者Martin Wiebusch
相关产品推荐
相关产品推荐

