如果与运行的Flask应用程序一起运行,grpc服务器将立即退出

时间:2019-05-29 10:20:03

标签: python multithreading flask grpc grpc-python

我试图在单个应用程序和容器中运行Flask REST API和gRPC API,由于某种原因,gRPC服务器在启动后立即关闭。

因此,我有一个简单的Flask应用程序,该应用程序提供一些REST端点。它有两个蓝图和具有标准入口点的引导程序:

#!/usr/bin/env python
from app import bootstrap

app_name = os.environ.get(C.KEYS.APP_NAME_KEY)
conf_data = bootstrap.get_conf_data(app_name)
flask_app = bootstrap.get_app(app_name, conf_data)
bootstrap.register_blueprints(flask_app)

if __name__ == '__main__':
    flask_app.run()

我创建了一个单独的模块,该模块实现了一个简单的gRPC接口,并且我想同时在同一应用程序和容器内的不同端口上同时运行这两个模块。默认的gRPC服务器实现使用futures.ThreadPoolExecutor并且是非阻塞的,因此我认为它应该能够在Flask应用执行的后台运行。 gRPC服务器引导程序如下所示:

import grpc
from concurrent import futures

from svc.auth_grpc import auth_pb2, auth_pb2_grpc


def start_server():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=1),
                         maximum_concurrent_rpcs=1)
    auth_pb2_grpc.add_AuthServiceServicer_to_server(AuthServiceServicer(),
                                                    server)
    server.add_insecure_port(f'0.0.0.0:9091')
    server.start()

由于我的目标是使gRPC和Flask共存-我将gRPC引导程序添加到应用程序入口点,如下所示:

if __name__ == '__main__':
    start_server()
    flask_app.run()

我希望gRPC将启动一个线程并无限期地在后台运行,而Flask将执行标准的阻塞werkzeug引导程序并将在前台运行。所有这些都是在开始时发生的,但是在Flask启动后的第二秒,gRPC队列CompletionQueue收到了SHUTDOWN事件,服务器退出了。

我不知道为什么会发生该事件以及触发该事件的原因,并且我无法深入研究CompletionQueue,因为它是下面的Cython实现。

单独运行gRPC服务器和Flask应用程序,其余所有代码均保持不变。

如何使这两个事件循环共存?

1 个答案:

答案 0 :(得分:0)

好吧,server函数完成后,start_server变量将被垃圾回收。这就是为什么gRPC服务器似乎立即关闭的原因。要解决此问题,可以使用全局变量来存储服务器对象。

此外,如果您认为此API设计不理想,请随时在GitHub存储库https://github.com/grpc/grpc上提交问题。