首页 > 解决方案 > REST API 上的 GUnicorn 和共享字典:高负载时出现“输入用尽”错误

问题描述

我正在使用 amanager.dict在与 GUnicorn (与 Meinheld 工作人员)一起服务的 API 的多个工作人员之间同步一些数据。虽然这适用于一些并发查询,但当我在 API 上同时触发大约 100 个查询时它会中断,并且会显示以下堆栈跟踪:

2020-07-16 12:35:38,972-app.api.my_resource-ERROR-140298393573184-on_post-175-Ran out of input
Traceback (most recent call last):
  File "/app/api/my_resource.py", line 163, in on_post
    results = self.do_something(a, b, c, **d)
  File "/app/user_data/data_lookup.py", line 39, in lookup_something
    return (a in self._shared_dict
  File "<string>", line 2, in __contains__
  File "/usr/local/lib/python3.6/multiprocessing/managers.py", line 757, in _callmethod
    kind, result = conn.recv()
  File "/usr/local/lib/python3.6/multiprocessing/connection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
EOFError: Ran out of input
2020-07-16 12:35:38,972-app.api.my_resource-ERROR-140298393573184-on_post-175-unpickling stack underflow
Traceback (most recent call last):
  File "/app/api/my_resource.py", line 163, in on_post
    results = self.do_something(a, b, c, **d)
  File "/app/user_data/data_lookup.py", line 39, in lookup_something
    return (a in self._shared_dict
  File "<string>", line 2, in __contains__
  File "/usr/local/lib/python3.6/multiprocessing/managers.py", line 757, in _callmethod
    kind, result = conn.recv()
  File "/usr/local/lib/python3.6/multiprocessing/connection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
_pickle.UnpicklingError: unpickling stack underflow

我的 API 框架是falcon。我有一个包含可以通过 POST 请求更新的用户数据的字典。架构应该很简单,所以我选择Manager.dict()multiprocessing包中存储数据。在进行其他查询时,将根据该字典 ( if a in self._shared_dict: ...) 的内容检查这些输入。这就是发生上述错误的地方。

为什么会出现这个问题?它似乎与manager.dict. 此外,当我在 PyCharm 中进行调试时,调试器也不会评估任何变量,并且通常只是无限地挂在multiprocessing等待数据的代码中的某个地方。

标签: pythonpython-multiprocessinggunicornfalconframework

解决方案


这似乎与Meinheld工人有关。当我将 GUnicorn 配置为使用默认sync工作类时,此错误不再发生。因此,PythonmultiprocessingMeinheld包在我的设置中似乎不能很好地工作。


推荐阅读