在使用Gunicorn和Gevent运行Flask时,请求包含请求的非阻塞请求

时间:2016-09-28 20:11:23

标签: python flask python-requests gunicorn gevent

My 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

3 个答案:

答案 0 :(得分:10)

如果您使用gunicorn部署Flask应用程序,它已经是非阻塞的。如果客户端正在等待您的某个视图的响应,则另一个客户端可以毫无问题地向同一视图发出请求。将有多个工作人员同时处理多个请求。无需更改代码即可实现此功能。这几乎适用于每个Flask部署选项。

答案 1 :(得分:6)

首先是一些背景,阻塞套接字是默认类型的套接字,一旦你开始阅读你的应用程序或线程在实际读取数据或断开连接之前无法重新获得控制权。这是python-requests默认运行的方式。有一个称为grequests的分拆,它提供非阻塞读取。

  

主要的机械差异是发送,接收,连接和接受   没有做任何事情就能回来。你有(当然)一个号码   选择。您可以检查返回代码和错误代码   让自己疯了。如果你不相信我,那就试试吧

来源:https://docs.python.org/2/howto/sockets.html

还接着说:

  

毫无疑问,最快的套接字代码使用非阻塞   套接字并选择多路复用它们。你可以把东西放在一起   这将使LAN连接饱和,而不会给网络带来任何压力   中央处理器。问题是以这种方式编写的应用程序无法做很多事情   其他任何事情 - 它需要随时准备好改变字节   次。

     

假设您的应用实际上应该做更多的事情   那,线程是最佳解决方案

但是你想通过让它产生自己的线程来为你的视图增加很多复杂性。特别是当gunicorn为async workers

  

可用的异步工作程序基于Greenlets(通过   Eventlet和Gevent)。 Greenlets是合作的实现   Python的多线程。通常,应用程序应该能够   使用这些工人类而不做任何更改。

  

需要异步工作者的行为的一些示例:应用程序   进行长时间阻止呼叫(即外部Web服务)

所以简而言之,不要改变任何东西!随它去吧。如果您要进行任何更改,请使用它来引入缓存。考虑使用Cache-control python-requests开发人员推荐的扩展。

答案 2 :(得分:1)

您可以使用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

编辑:我已经添加了一项测试,并发现由于枪手的gevent工作者在初始化时已经执行了猴子修补,所以时间没有因为问题而改善:https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/ggevent.py#L65 < / p>