为什么gevent在Apache + mod_wsgi的Flask应用程序中引发NotImplementedError?
我在使用Apache(mod_wsgi) 和gevent共享主机(Webfaction)部署我的Flask应用程序时遇到问题。为什么gevent在Apache + mod_wsgi的Flask应用程序中引发NotImplementedError?
应用程序工作在由瓶提供的开发服务器,但是当我 尝试部署它,我得到的日志文件中出现以下错误:因为我使用了python-requests' async module
[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到 发出并发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}
思想来自另一answer在那里建议WSGIApplicationGroup设置为GLOBAL解决与一个WSGI的过程,保持崩溃的问题。 From WSGI documentation:
要强制特定WSGI应用中时的Python被初始化时, WSGIApplicationGroup指令应使用的组设置为 “%{GLOBAL}”创建第 的Python子解释器内运行的。
不能完全理解为什么这个指令解决了我的问题,但它确实如此。我会很乐意,如果有人能够用简单的英语向;-)给我讲解一下
请参见[为什么是方法,使用gevent-in-a-mod-wsgi-deployed-flask-api-raising-error](http://serverfault.com/questions/754841/why-is -method-that-uses-gevent-in-a-mod-wsgi-deployed-flask-api-raising-error-ab)......很遗憾,如此迟到的游戏,但我终于有了答案。 – 2016-08-18 18:22:57
为什么-1这个? “无法完全理解为什么这个指令能解决我的问题,但它确实如此”的问题的相关答案是“我在这里找到了答案:为什么指令WSGIApplicationGroup%{GLOBAL}可用于创建新线程 简而言之: WSGIApplicationGroup:设置执行相同的Python解释器下运行(首先创建的) 所以,在默认情况下,每一个新的线程一定是没有使用相同的Python解释器实例 对于uWSGI,等效方法是将其添加到.ini文件中: single-interpreter = true“ – 2016-09-26 18:08:57
尝试用monkey.patch_all(thread=False)
代替monkey.patch_all()
。如果它实际上是修补时引起故障的线程模块,则应该解决它。 request
不使用线程。
谢谢西蒙,我试过这个解决方案,但我一直得到同样的错误。 – raben 2012-03-14 16:29:28
我下面贴的答案上https://serverfault.com/a/869625/355861
的apache的mod_wsgi目前不兼容GEVENT。对于使用Apache的AWS弹性Beanstalk,我对Flask使用async_mode =“threading”,它运行良好。请注意,线程的性能低于gevent。 https://flask-socketio.readthedocs.io/en/latest/#deployment
app = Flask(__name__,static_folder='static')
socketio = SocketIO(app, async_mode="threading")
注意瓶可以用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。
这是你的httpd.conf中WSGIDaemonProcess的值吗? – Masci 2012-03-13 21:50:07
可能是因为根据我的经验gevent有点不高兴,如果只有在其他人已经导入并以某种方式使用它时猴子才会修补Python线程模块。正在导致我无法解决某些问题。尽管如此,还没有机会深入研究问题。 – 2012-03-13 23:47:17
@Masci我更新了一个链接到我的httpd.conf和WSGIDaemonProcess的值 – raben 2012-03-14 14:08:40