负载均衡器调用gRPC服务报错:unknown service fooService.FooService
unknown service fooService.FooService错误的思路 我来帮你捋捋这个问题——你遇到的错误提示明显有点“张冠李戴”:明明调用的是RedisGateway服务,却提示找不到完全不相关的fooService.FooService,结合你说其他gRPC服务都正常,这个问题大概率出在负载均衡器的路由配置上,而非服务代码本身。
下面是几个针对性的排查方向:
先查负载均衡器的路由映射是否错位
错误提示里的服务名和你实际调用的redis-gateway完全不匹配,最大的可能是负载均衡器把指向redis-gateway:10006的请求,错误转发到了foo-service的后端实例上。
你需要仔细核对负载均衡器中针对redis-gateway的转发规则:- 确认目标服务的DNS名称是不是被误写成了
foo-service? - 检查端口映射有没有串线——比如是不是把
10006端口的流量导去了foo-service的端口?
- 确认目标服务的DNS名称是不是被误写成了
用grpcurl验证目标服务的实际暴露内容
你可以在客户端环境里用grpcurl工具直接探测redis-gateway:10006的服务列表,看看返回的是不是你预期的RedisGateway服务:grpcurl -plaintext redis-gateway:10006 list如果这条命令返回的是
fooService.FooService,那实锤是负载均衡器的路由配置错误;如果返回的是rs.RedisGateway,再往下排查服务注册的问题。检查服务注册中心的一致性(如果用了的话)
如果你用了服务注册发现组件(比如K8s Service、Consul、Etcd),需要确认:redis-gateway服务的注册信息是否正确?服务名、端口、gRPC元数据有没有和其他正常服务对齐?- 有没有可能
redis-gateway的实例在注册中心里被错误标记成了fooService?或者负载均衡器拉取的服务列表中,redis-gateway的条目指向了错误的后端?
临时绕开负载均衡器做验证
直接用redis-gateway服务实例的真实IP+端口替换客户端代码里的redis-gateway:10006,重新调用试试。如果直接调用能正常返回结果,那100%是负载均衡器的路由问题;如果还是报错,再回头检查服务端的proto生成代码和注册逻辑(不过从你贴的代码看,这部分应该没问题)。
补充一句:你的服务端和客户端代码看起来都没问题——服务端正确注册了RedisGatewayServer,客户端也用了对应的rs.NewRedisGatewayClient,proto配置无误的话,代码层面不会出现这种跨服务的错误提示。
内容的提问来源于stack exchange,提问作者MATT SHALLOW

