[英]how to make a non-blocking request with requests when running Flask with Gunicorn and Gevent
[英]Make a non-blocking request with requests when running Flask with Gunicorn and Gevent
我的Flask应用程序将收到一个请求,进行一些处理,然后向一个需要5秒钟响应的慢速外部端点发出请求。 看起来使用Gevent运行Gunicorn将允许它同时处理许多这些慢速请求。 如何修改下面的示例以使视图无阻塞?
import requests
@app.route('/do', methods = ['POST'])
def do():
result = requests.get('slow api')
return result.content
gunicorn server:app -k gevent -w 4
如果您使用gunicorn部署Flask应用程序,它已经是非阻塞的。 如果客户端正在等待您的某个视图的响应,则另一个客户端可以毫无问题地向同一视图发出请求。 将有多个工作人员同时处理多个请求。 无需更改代码即可实现此功能。 这也适用于几乎所有Flask部署选项。
首先是一些背景,阻塞套接字是默认类型的套接字,一旦你开始阅读你的应用程序或线程在实际读取数据或断开连接之前无法重新获得控制权。 这就是python-requests
的默认操作方式。 有一个名为grequests
,它提供非阻塞读取。
主要的机械差异是send,recv,connect和accept可以在没有做任何事情的情况下返回。 你(当然)有很多选择。 您可以检查返回代码和错误代码,通常会让自己发疯。 如果你不相信我,请尝试一下
资料来源: https : //docs.python.org/2/howto/sockets.html
它还继续说:
毫无疑问,最快的套接字代码使用非阻塞套接字并选择多路复用它们。 您可以将可以使LAN连接饱和的东西放在一起,而不会给CPU带来任何压力。 麻烦的是,以这种方式编写的应用程序无法做任何其他事情 - 它需要随时准备好随机播放字节。
假设您的应用实际上应该做更多的事情,线程是最佳解决方案
但是,您是否希望通过生成自己的线程来为视图添加大量复杂性。 特别是当gunicorn作为异步工人 ?
可用的异步工作程序基于Greenlets(通过Eventlet和Gevent)。 Greenlets是Python的协作多线程的实现。 通常,应用程序应该能够使用这些工作类而不进行任何更改。
和
需要异步工作程序的一些行为示例:进行长阻塞调用的应用程序(即外部Web服务)
所以长话短说,不要改变任何东西! 随它去吧。 如果您要进行任何更改,请使用它来引入缓存。 考虑使用由python-requests开发人员推荐的扩展控件 。
您可以使用grequests
。 它允许其他greenlet在请求时运行。 它与requests
库兼容并返回requests.Response
对象。 用法如下:
import grequests
@app.route('/do', methods = ['POST'])
def do():
result = grequests.map([grequests.get('slow api')])
return result[0].content
编辑:我添加了一个测试,看到时间没有随着问候而改善,因为gunicorn的gevent worker在初始化时已经执行了猴子修补: https : //github.com/benoitc/gunicorn/blob/master/gunicorn /workers/ggevent.py#L65
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.