为什么使用 Apache + mod_wsgi 的 Flask 应用程序上的 gevent 会引发 NotImplementedError?

StackOverflow https://stackoverflow.com//questions/9692089

我遇到了与Apache(MOD_WSGI)一起部署烧瓶应用程序的问题,并在共享托管(WebFaction)上遇到了问题。

该应用程序在烧瓶提供的开发服务器中正常工作,但是当我尝试部署它时,我会在日志文件中获得以下错误:

[Tue Mar 13 15:48:24 2012] [error] Traceback (most recent call last):
[Tue Mar 13 15:48:24 2012] [error]   File "evdns.pxi", line 78, in gevent.core.__evdns_callback (gevent/core.c:6300)
[Tue Mar 13 15:48:24 2012] [error]   File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 297, in switch_args
[Tue Mar 13 15:48:24 2012] [error]   File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 290, in switch
[Tue Mar 13 15:48:24 2012] [error]   File "/home/username/.virtualenvs/staging/lib/python2.7/site-packages/gevent/hub.py", line 135, in get_hub
[Tue Mar 13 15:48:24 2012] [error] NotImplementedError: gevent is only usable from a single thread

我需要 gevent 因为我正在使用 python-requests 的异步模块 提出并发的HTTP请求。我尝试谷歌搜索,但我发现的唯一建议是打电话

from gevent import monkey
monkey.patch_all()

我已经在代码中做了一些事情。

的价值 WSGIDaemonProcess 是:

WSGIDaemonProcess myapp processes=5 python-path=/home/myusername/webapps/myapp/lib/python2.7 threads=1

这是我的 httpd.conf: http://pastebin.com/eWygicJH

有人有解决这个问题的建议吗?

有帮助吗?

解决方案

似乎我自己找到了解决方案。以下指令已解决我的问题:

WSGIApplicationGroup %{GLOBAL}
.

这个想法来自另一个答案,建议将WSGIAPplicationGroup设置为全局来解决WSGI进程的问题这保持崩溃。来自wsgi文档

强制特定的WSGI应用程序在第一个应用程序中运行 Python子解释器创建Python初始化时, 应该使用WSGIAPplicationGroup指令,并将组设置为 '%{global}'。

无法完全理解为什么这个指令解决我的问题,但它确实如此。如果有人能够用简单的英语解释这件事,我将比快乐; - )

其他提示

尝试更换 monkey.patch_all()monkey.patch_all(thread=False). 。如果确实是线程模块在修补时引起了问题,那么这应该可以解决它。 request 不使用线程。

我在 https://serverfault.com/a/869625/355861

apache mod_wsgi当前不兼容gvent。对于APACHE的AWS Elastic Beanstalk,我使用了async_mode=“线程”for flask,它运行良好。注意,线程的性能比GEVent少。 https://flask-socketio.readthedocs.io/en/latest/#deployment

app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="threading") 
.

请注意,烧瓶可以使用gvent运行独立式。

app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="gevent") 

if __name__ == '__main__':
    HOST = '127.0.0.1'
    PORT = 5055
    socketio.run(app, port=PORT, host=HOST)
. 但是,您真的需要在它前面的HTTP服务器,例如枪手。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top