GUnicorn 和 REST 上的共享字典 API:"Ran out of input" 高负载时出错

GUnicorn and shared dictionary on REST API: "Ran out of input" Error on high load

我正在使用 manager.dict 在 API 的多个工作人员之间同步一些数据,这些工作人员使用 GUnicorn(与 Meinheld 工作人员一起)。虽然这对于一些并发查询工作正常,但当我在 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 请求更新。架构应该很简单,所以我选择了 multiprocessing 包中的 Manager.dict() 来存储数据。在进行其他查询时,将根据该词典的内容检查这些输入 (if a in self._shared_dict: ...)。这就是上面提到的错误发生的地方。

为什么会出现这个问题?它似乎与manager.dict有关。此外,当我在 PyCharm 中进行调试时,也会发生调试器不计算任何变量并且经常在 multiprocessing 代码等待数据的地方无限挂起。

好像跟Meinheld工人有关系。当我将 GUnicorn 配置为使用默认 sync worker class 时,此错误不再发生。因此,Python multiprocessingMeinheld 包在我的设置中似乎效果不佳。