我想通过Apache / mod_wsgi部署一个Flask api。 api使用Gevent为recursion方法提供并发性。 但是,这是抛出以下错误
[Mon Feb 08 12:05:37 2016] [error] error: cannot switch to a different thread [Mon Feb 08 12:05:37 2016] [error] <callback at 0x1094ee350 args=()> failed with error
当使用Pycharm的内置web服务器运行时,整个api运行得很好,而当我不使用gevent来提供并发时,使用Apache / mod_wsgi很好地部署api。
我认为这应该可以在Apache中运行,但我到目前为止还没有find解决scheme。 我一直看到提及猴子修补,所以我把这一行添加到gevent被调用的模块
from gevent import monkey; monkey.patch_all()
但是,这似乎没有帮助。
我在Flask文档( http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/ )上的独立WSGI容器中发现了这一点:
Gevent is a coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of libevent event loop: from gevent.wsgi import WSGIServer from yourapplication import app http_server = WSGIServer(('', 5000), app) http_server.serve_forever()
它也是这样说的
There are popular servers written in Python that contain WSGI applications and serve HTTP. These servers stand alone when they run; you can proxy to them from your web server. Note the section on Proxy Setups if you run into issues.
我是否需要使用mod_wsgi并使用Gevent的内置WSGI服务器,然后通过Apache进行代理? 这将是一个皇家PITA,尤其是处理CORS问题(我们有一个Web UI访问同一台服务器上的API,而从不同端口进行代理会导致交叉产生问题 – 除非有人能说服我)。
任何有关下一步尝试的见解将是最受赞赏的。
apache mod_wsgi目前不兼容gevent。 对于使用Apache的AWS弹性bean,我对Flask使用了async_mode =“threading”,它运行良好。 请注意,线程的性能比geventless。
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。
我刚刚发现了一个类似的线程在这里https://stackoverflow.com/questions/9692089/why-gevent-on-a-flask-app-with-apache-mod-wsgi-is-raising-notimplementederror有解决scheme。
要做我所需要的,我必须添加指令WSGIApplicationGroup %{GLOBAL}到我的Apache conf。 我也很好奇,为什么这解决了这个问题。
我在这里find答案: 为什么指令WSGIApplicationGroup%{GLOBAL}用于创build新线程
简而言之:
WSGIApplicationGroup:将执行设置为在同一个Python解释器(第一个创build的)下运行。
所以,默认情况下,每个新线程都不能使用相同的python解释器实例。
对于uWSGI,等效的方法是将其添加到.ini文件中:
single-interpreter = true