简体   繁体   English

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

[英]Why gevent on a Flask app with Apache + mod_wsgi is raising NotImplementedError?

I'm having an issue deploying my Flask app with Apache (mod_wsgi) and gevent on a shared hosting (Webfaction). 我在使用Apache(mod_wsgi)和gevent在共享主机(Webfaction)上部署我的Flask应用程序时遇到问题。

The application works fine in the development server provided by Flask, but when I try to deploy it I get the following error in log file: 该应用程序在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

I need gevent because I'm using the python-requests' async module to make concurrent HTTP requests. 我需要gevent,因为我正在使用python-requests'异步模块来发出并发HTTP请求。 I tried to Google around but the only advice I found is to to call 我尝试了谷歌,但我发现的唯一建议是打电话

from gevent import monkey
monkey.patch_all()

something that I already do in my code. 我在代码中已经做过的事情。

The value of WSGIDaemonProcess is: WSGIDaemonProcess的值是:

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

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

Anybody has any advice to solve this issue? 有人有任何建议来解决这个问题吗?

It seems like i found the solution myself. 好像我自己找到了解决方案。 The following directive solved my issue: 以下指令解决了我的问题:

WSGIApplicationGroup %{GLOBAL}

The idea comes from another answer where it is suggested to set WSGIApplicationGroup to GLOBAL to solve a problem with a WSGI process that keep crashing. 这个想法来自另一个答案 ,建议将WSGIApplicationGroup设置为GLOBAL以解决持续崩溃的WSGI进程的问题。 From WSGI documentation : 来自WSGI文档

To force a specific WSGI application to be run within the very first Python sub interpreter created when Python is initialised, the WSGIApplicationGroup directive should be used and the group set to '%{GLOBAL}'. 要强制特定的WSGI应用程序在初始化Python时创建的第一个Python子解释器中运行,应使用WSGIApplicationGroup指令并将该组设置为'%{GLOBAL}'。

Cannot fully understand why this directive solve my issue but it does. 无法完全理解为什么这个指令解决了我的问题,但确实如此。 I will be more than happy if someone is able to explain this to me in plain English ;-) 如果有人能够用简单的英语向我解释这一点,我将非常高兴;-)

Try replacing monkey.patch_all() with monkey.patch_all(thread=False) . 尝试用monkey.patch_all() monkey.patch_all(thread=False)替换monkey.patch_all() monkey.patch_all(thread=False) If it's really the threading module which is causing the trouble when patched, this should solve it. 如果它确实是在修补时导致问题的线程模块,那么应该解决它。 request does not use threading. request不使用线程。

I posted below answer on https://serverfault.com/a/869625/355861 我在https://serverfault.com/a/869625/355861上发布了以下答案

apache mod_wsgi is not currently compatible with gevent. apache mod_wsgi目前不兼容gevent。 For AWS elastic beanstalk with Apache, I used async_mode="threading" for Flask and it works well. 对于使用Apache的AWS弹性beanstalk,我对Flask使用了async_mode =“threading”,它运行良好。 Note, threading has less performance than gevent. 注意,线程的性能低于gevent。 https://flask-socketio.readthedocs.io/en/latest/#deployment https://flask-socketio.readthedocs.io/en/latest/#deployment

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

Note that Flask can run standalone with gevent. 请注意,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)

However, you really want an HTTP server in front of it such as Gunicorn. 但是,你真的想在它前面有一个HTTP服务器,比如Gunicorn。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM