我已经使用proto3和python创建了一个gRPC服务器,以对运行时间较长的守护程序进行基本的运行状况检查。但是,当我启动应用程序时,它实际上并没有启动gRPC服务器。我想知道是否有人可以帮助确定为什么它无法启动并提供gRPC API
原型定义:health.proto
syntax = "proto3"; option java_multiple_files = true; option java_package = "com.redacted.example.worker"; option java_outer_classname = "ExampleWorker"; option objc_class_prefix = "DSW"; package exampleworker; service Worker { rpc Health (Ping) returns (Pong) {} } // The request message containing PONG message Ping { string message = 1; } // The response message containing PONG message Pong { string message = 1; }
然后我使用以下命令生成了python代码:
python -m grpc_tools.protoc -I=../protos --python_out=. --grpc_python_out=. ../protos/health.proto
这生成了health_pb2.py
和health_pb2_grpc.py
文件。接下来,我创建了一个服务器文件:
u"""Health server is used to create a new health monitoring GRPC server.""" from concurrent import futures import logging import grpc import health_pb2 import health_pb2_grpc # grpc related variables grpc_host = u'[::]' grpc_port = u'50001' grpc_address = u'{host}:{port}'.format(host=grpc_host, port=grpc_port) # logging related variables logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) class WorkerServicer(health_pb2_grpc.WorkerServicer): u"""Provides methods that implement functionality of health server.""" def Health(self, request, context): u"""Return PONG to say the Worker is alive.""" return health_pb2.Pong(message='PONG') def serve_health_api(): u"""Create and start the GRPC server.""" server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) health_pb2_grpc.add_WorkerServicer_to_server(WorkerServicer(), server) logging.info(u'adding port {grpc_address}'.format( grpc_address=grpc_address)) server.add_insecure_port(grpc_address) server.start()
然后在我的主要run.py文件中:
#!mac/bin/python """Run is the local (non-wsgi) entrypoint to the flask application.""" from subscriber.worker import Worker from redis import StrictRedis from examplegrpc.health_server import serve_health_api import logging redis_host = 'localhost' redis_port = 6379 redis_db = 0 redis_chan = 'deployment' if __name__ == "__main__": FORMAT = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s' logging.basicConfig(format=FORMAT) logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) logger.debug('Creating redis client') client = StrictRedis(host=redis_host, port=redis_port, db=redis_db) w = Worker(client, [redis_chan]) try: logger.info('Starting Health gRPC API...') serve_health_api() logger.info('Starting worker...') w.run() except KeyboardInterrupt: logger.info('Exiting...')
w.run()可以正确启动以执行Redis通道上的工作,但是gRPC服务器无法启动,原因是尝试使用
channel = grpc.insecure_channel('localhost:{port}'.format(port=grpc_port)) stub = WorkerStub(channel) ping = examplegrpc.health_pb2.Ping(message='PING') health = stub.Health(ping)
开始
_Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNAVAILABLE, Connect Failed)>
小智.. 5
在我看来,正在发生的事情是服务器仅分配给serve_health_api
函数中的本地字段,因此当该函数返回(启动服务器后立即)返回时,服务器将被垃圾回收并关闭。
在我看来,正在发生的事情是服务器仅分配给serve_health_api
函数中的本地字段,因此当该函数返回(启动服务器后立即)返回时,服务器将被垃圾回收并关闭。