使用Gunicorn和Geven运行Flask时,使用请求发出非阻塞请求

2024-04-19 21:14:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我的Flask应用程序将接收一个请求,进行一些处理,然后向一个慢的外部端点发出一个请求,该请求需要5秒的响应时间。看起来运行Gunicorn和Gevent将允许它同时处理许多缓慢的请求。如何修改下面的示例以使视图不被阻塞?

import requests

@app.route('/do', methods = ['POST'])
def do():
    result = requests.get('slow api')
    return result.content
gunicorn server:app -k gevent -w 4

Tags: import视图app应用程序flask示例时间gevent
3条回答

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

编辑:我添加了一个测试,发现时间并没有随着grequests而增加,因为gunicorn的gevent工作程序在初始化时已经执行了猴子修补:https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/ggevent.py#L65

首先是背景,阻塞套接字是默认类型的套接字,一旦开始读取应用程序或线程,在实际读取数据或断开连接之前不会重新获得控制权。默认情况下,python-requests就是这样操作的。有一个称为grequests的派生,它提供非阻塞读取。

The major mechanical difference is that send, recv, connect and accept can return without having done anything. You have (of course) a number of choices. You can check return code and error codes and generally drive yourself crazy. If you don’t believe me, try it sometime

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

它还说:

There’s no question that the fastest sockets code uses non-blocking sockets and select to multiplex them. You can put together something that will saturate a LAN connection without putting any strain on the CPU. The trouble is that an app written this way can’t do much of anything else - it needs to be ready to shuffle bytes around at all times.

Assuming that your app is actually supposed to do something more than that, threading is the optimal solution

但是你想通过让它产生自己的线程来增加你的视图的复杂性吗。尤其是当gunicorn作为async workers时?

The asynchronous workers available are based on Greenlets (via Eventlet and Gevent). Greenlets are an implementation of cooperative multi-threading for Python. In general, an application should be able to make use of these worker classes with no changes.

以及

Some examples of behavior requiring asynchronous workers: Applications making long blocking calls (Ie, external web services)

所以长话短说,不要改变任何事情!就这样吧。如果您要做任何更改,就让它引入缓存。考虑使用python请求开发人员推荐的扩展名Cache-control

如果使用gunicorn部署Flask应用程序,它已经是非阻塞的。如果客户机正在等待您的某个视图的响应,则另一个客户机可以向同一个视图发出请求,而不会出现问题。将有多个工人同时处理多个请求。不需要更改代码就可以工作。这也适用于几乎所有的烧瓶部署选项。

相关问题 更多 >