You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gRPC HealthCheck配置为NOT_SERVING却返回SERVING问题求助

问题根因

  1. gRPC中同一个服务的全限定名(这里是grpc.health.v1.Health)只能绑定一个servicer实现,你先后把Greeter、Byeer作为HealthServicer注册到服务器,后注册的会直接覆盖前一个,这就是为什么所有健康检查请求都走到Greeter的Check逻辑,永远返回SERVING。
  2. 你自定义的Check方法没有处理请求参数里的service字段,不管传入的要查询的服务名是什么,都直接返回固定状态,完全没有做服务名匹配判断。
  3. 不需要让业务服务类自己实现HealthServicer接口,gRPC官方的grpc_health.v1.health模块已经提供了现成的HealthServicer实现,支持独立管理多个服务的健康状态,直接调用即可,不需要自己写Check/Watch方法。

额外小提示:你原代码中Byeer的SayBye方法返回的是HelloReply类型,不符合proto定义,修复时可以顺便修正。


修复后的服务端代码

from concurrent import futures
import grpc
from grpc_health.v1 import health, health_pb2, health_pb2_grpc
from grpc_reflection.v1alpha import reflection
import test_pb2_grpc
import test_pb2


class Greeter(test_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        return test_pb2.HelloReply(message='Hello, %s!' % request.name)


class Byeer(test_pb2_grpc.ByeerServicer):
    def SayBye(self, request, context):
        return test_pb2.ByeReply(message='Bye, %s!' % request.name)


def run_server():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=None))
    server.add_insecure_port('[::]:8000')

    # 注册业务服务
    test_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    test_pb2_grpc.add_ByeerServicer_to_server(Byeer(), server)

    # 初始化官方Health服务实例,统一管理所有服务健康状态
    health_servicer = health.HealthServicer()
    health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server)
    # 分别设置两个业务服务的健康状态
    health_servicer.set("test.Greeter", health_pb2.HealthCheckResponse.SERVING)
    health_servicer.set("test.Byeer", health_pb2.HealthCheckResponse.NOT_SERVING)
    # 可选:设置全局(空服务名)的健康状态
    health_servicer.set("", health_pb2.HealthCheckResponse.SERVING)

    # 开启反射
    services = tuple(service.full_name for service in health_pb2.DESCRIPTOR.services_by_name.values())
    services += tuple(service.full_name for service in test_pb2.DESCRIPTOR.services_by_name.values())
    services += (reflection.SERVICE_NAME,)
    reflection.enable_server_reflection(services, server)

    server.start()
    server.wait_for_termination()


if __name__ == "__main__":
    run_server()

验证效果

修改后再调用健康检查接口就能得到预期结果:

  • 查询test.Greeter返回SERVING
  • 查询test.Byeer返回NOT_SERVING
  • 查询不存在的服务名会返回NOT_FOUND状态码,不会再错误返回SERVING

内容的提问来源于stack exchange,提问作者Occam's razor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:15:04