首页 > 解决方案 > 尝试使用 Heroku 上的 Multiprocessing BaseManager 连接到工作进程时出现 ConnectionRefusedError

问题描述

我制作了一个烧瓶网络应用程序,它使用 python 进行一些机器学习,我目前正在尝试将它部署到 Heroku(使用免费计划)。在开发服务器上和运行时一切都运行良好heroku local,但是在部署应用程序时我遇到了实时版本的问题。

该应用程序由两个 dyno、一个运行主应用程序的 web dyno 和一个 worker 组成。worker 为地址 127.0.0.1:22109 的 multiprocessing.managers.BaseManager 提供服务,用于管理这样的共享 python对象。该对象处理作为机器学习任务基础的所有状态和功能。

当我从 web 应用程序启动机器学习任务时,web dyno 中的进程应该连接到 worker dyno 上的 Manager,以便应用程序可以与之交互,但我收到 ConnectionRefusedError:

2021-08-18T13:25:55.657204+00:00 app[web.1]: ERROR:neuralnetworkwebapp:Exception on /network-widget/train [GET]
2021-08-18T13:25:55.657214+00:00 app[web.1]: Traceback (most recent call last):
2021-08-18T13:25:55.657231+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
2021-08-18T13:25:55.657233+00:00 app[web.1]: response = self.full_dispatch_request()
2021-08-18T13:25:55.657240+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
2021-08-18T13:25:55.657240+00:00 app[web.1]: rv = self.handle_user_exception(e)
2021-08-18T13:25:55.657240+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
2021-08-18T13:25:55.657241+00:00 app[web.1]: rv = self.dispatch_request()
2021-08-18T13:25:55.657241+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
2021-08-18T13:25:55.657241+00:00 app[web.1]: return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
2021-08-18T13:25:55.657242+00:00 app[web.1]: File "/app/neuralnetworkwebapp/views.py", line 134, in train_network
2021-08-18T13:25:55.657242+00:00 app[web.1]: manager = get_manager(current_app)
2021-08-18T13:25:55.657243+00:00 app[web.1]: File "/app/neuralnetworkwebapp/persistence.py", line 29, in get_manager
2021-08-18T13:25:55.657244+00:00 app[web.1]: manager.connect()
2021-08-18T13:25:55.657244+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/multiprocessing/managers.py", line 522, in connect
2021-08-18T13:25:55.657245+00:00 app[web.1]: conn = Client(self._address, authkey=self._authkey)
2021-08-18T13:25:55.657245+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/multiprocessing/connection.py", line 507, in Client
2021-08-18T13:25:55.657245+00:00 app[web.1]: c = SocketClient(address)
2021-08-18T13:25:55.657246+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/multiprocessing/connection.py", line 635, in SocketClient
2021-08-18T13:25:55.657246+00:00 app[web.1]: s.connect(address)
2021-08-18T13:25:55.657246+00:00 app[web.1]: ConnectionRefusedError: [Errno 111] Connection refused

这些是persistance.py 中的两个函数,它们处理管理器的创建(init_manager)和与它的后续连接(get_manager):

def init_manager(host, port, key):
    manager = StateManager(address=(host, port), authkey=key)
    server = manager.get_server()
    print(f'HOST: {host}\nPORT: {port}')
    server.serve_forever()


def get_manager(app):
    manager = StateManager(address=(app.config['MANAGER_HOST'], app.config['MANAGER_PORT']), authkey=app.config['MANAGER_AUTHKEY'])
    manager.register('TrainNetwork')
    manager.connect()
    return manager

StateManager 只是我的 BaseManager 的子类。

当我尝试在 web dyno 中调用 get_manager 时出现错误。我一直在努力寻找解决方案,但我对此很陌生,我有点难过。我不确定它是否有用,但这是我用来运行应用程序的 procfile:

worker: python runmanager.py
web: waitress-serve --call --port=$PORT neuralnetworkwebapp:create_app

这就是我在 runmanager.py 中调用 init_manager 的方式

    MANAGER_HOST = '127.0.0.1'
    MANAGER_PORT = 22109

    MANAGER_AUTHKEY = bytes(os.environ.get('MANAGER_AUTHKEY'), 'utf8')

    init_manager(MANAGER_HOST, MANAGER_PORT, MANAGER_AUTHKEY)

我知道当使用服务员为 Web 进程提供服务时,端口由 Heroku 分配并通过环境变量提供。工作进程是否会发生类似的事情,这意味着我不应该在地址中硬编码为 127.0.0.1:22109?我还在某处阅读了有关免费计划可能的连接限制的评论,但我没有找到任何其他信息或我可以尝试实施的潜在修复。

任何帮助将非常感激。

标签: pythonflaskherokumultiprocessingconnection

解决方案


推荐阅读