Gunicorn ImportError: 在 Docker 中无法从 'eventlet.wsgi' 导入名为 'ALREADY_HANDLED' 的名称

31

我在 docker 中成功运行了使用 Flask 和 gunicorn (eventlet worker) 的代码。它在生产环境中也正常工作,但在我的电脑上却开始出现问题。我在谷歌上找不到任何关于这个问题的信息。可能会是什么问题呢?

Error: class uri 'eventlet' invalid or not found:
web_1       |
web_1       | [Traceback (most recent call last):
web_1       |   File "/root/.local/lib/python3.7/site-packages/gunicorn/util.py", line 99, in load_class
web_1       |     mod = importlib.import_module('.'.join(components))
web_1       |   File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
web_1       |     return _bootstrap._gcd_import(name[level:], package, level)
web_1       |   File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
web_1       |   File "<frozen importlib._bootstrap>", line 983, in _find_and_load
web_1       |   File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
web_1       |   File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
web_1       |   File "<frozen importlib._bootstrap_external>", line 728, in exec_module
web_1       |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
web_1       |   File "/root/.local/lib/python3.7/site-packages/gunicorn/workers/geventlet.py", line 20, in <module>
web_1       |     from eventlet.wsgi import ALREADY_HANDLED as EVENTLET_ALREADY_HANDLED
web_1       | ImportError: cannot import name 'ALREADY_HANDLED' from 'eventlet.wsgi' (/root/.local/lib/python3.7/site-packages/eventlet/wsgi.py)
web_1       | ]
3个回答

41

11
请注意:此版本存在WebSocket DOS漏洞。GHSA-9p9m-jm8w-94p2是导致这个重大变化的原因。 - jmunsch
3
很遗憾,在 Python 3.10 上这对我没用。 - Kuznetsov-M
Python 3.8无法工作。 - Frankie Drake
1
由于Python 3.11不兼容(eventlet==0.33.3, gunicorn==20.1.0),无法正常工作。 - Robin van Leeuwen

10

在尝试使用Flask和SocketIO时,我遇到了完全相同的错误,并在https://localcoder.org/deploy-flask-socketio-on-beanstalk上找到了答案。

按照他们的建议,我成功地运行了它。

pip uninstall gunicorn
pip uninstall eventlet
pip install gunicorn==20.1.0
pip install eventlet==0.30.2

gunicorn --worker-class eventlet -w 1 app:app

环境:AWS ALB -> EC2/Linux2 (Python 3.8.5, Flask Socket.IO)


10

看起来最近对于 eventlet 进行了更改。

请参考此 PR 的示例补丁,并查看潜在的发布版本:https://github.com/benoitc/gunicorn/pull/2581

Eventlet 0.30.3+ 移除了 wsgi.ALREADY_HANDLED,仅通过一个修补版本就破坏了公共 API。很抱歉。

ALREADY_HANDLED 的问题:eventlet/eventlet#543 使用 WSGI_LOCAL 的解决方法:eventlet/eventlet#544

建议使用 eventlet>=0.31.0 版本,如果使用 websockets,因为旧版本易受 DoS 攻击影响。GHSA-9p9m-jm8w-94p2

CI 在我未修改的行中未通过 pylint 检查。


1
嗯,我有docker alpine3.8和eventlet==0.33.0,但仍然出现错误ImportError: cannot import name 'ALREADY_HANDLED' from 'eventlet.wsgi'。 - sqp_125
1
@sqp_125 请查看:https://github.com/benoitc/gunicorn/pull/2581#issuecomment-994198667 - jmunsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接