为什么使用Apache + mod_wsgi对Flask应用程序进行gevent会引发NotImplementedError?

时间:2012-03-13 21:00:52

标签: python apache mod-wsgi flask gevent

我在使用Apache(mod_wsgi)部署我的Flask应用程序时遇到问题 和共享托管(Webfaction)上的gevent。

该应用程序在Flask提供的开发服务器中运行良好,但是当我 尝试部署它我在日志文件中收到以下错误:

[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' async module 制作并发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

有人有任何建议可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

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

WSGIApplicationGroup %{GLOBAL}

这个想法来自另一个answer,建议将WSGIApplicationGroup设置为GLOBAL以解决持续崩溃的WSGI进程的问题。 From WSGI documentation

  

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

无法完全理解为什么这个指令解决了我的问题,但确实如此。如果有人能用简单的英语向我解释,我会非常高兴; - )

答案 1 :(得分:1)

尝试将monkey.patch_all()替换为monkey.patch_all(thread=False)。如果它确实是在修补时导致问题的线程模块,那么应该解决它。 request不使用线程。

答案 2 :(得分:0)

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

上发布了以下答案

apache mod_wsgi目前与gevent不兼容。对于使用Apache的AWS弹性beanstalk,我使用了async_mode =" threading"对于Flask而言效果很好。注意,线程的性能低于gevent。 https://flask-socketio.readthedocs.io/en/latest/#deployment

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

请注意,Flask可以与gevent一起独立运行。

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服务器,比如Gunicorn。