如何通过gevent(与uwsgi结合使用)获得并发收益?

时间:2018-10-09 23:48:57

标签: python python-3.x flask gevent

我试图了解如何实现gevent的猴子补丁应该提供的异步优势。

要对此进行测试,我创建了一个测试服务器。

from gevent import monkey
monkey.patch_all()
from flask import Flask
from time import sleep
import requests

app = Flask(__name__)


def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)


@app.route('/')
def hello_world():
    return 'Hello, World!'


@app.route('/sleep/<int:n>')
def sleep_view(n):
    sleep(n)
    return f'Slept {n}'


@app.route('/slowreq')
def slowreq_view():
    res = requests.get('http://localhost:8002/sleep/5')
    return 'From another server: ' + res.text


@app.route('/fib/<int:n>')
def fib_view(n):
    x = fib(n)
    return str(x)


if __name__ == '__main__':
    import sys
    port = 8001
    threaded = False
    if len(sys.argv) > 1:
        port = int(sys.argv[1])
        threaded = True
    print(f'Threaded is {threaded}')
    app.run(port=port, threaded=threaded)

如果我在两个进程中运行它,首先使用python3 test.py(在8001上运行,flask是非线程的,但猴子已修补),然后在python3 test.py 8002(运行在8002上,flask是线程的,也猴子打补丁),我希望会发生以下情况:

  1. 在两个终端中,我一个接一个地快速运行time curl http://localhost:8001/slowreq/slowreq在另一台服务器上调用/sleep/5,因此作为一个独立的请求,需要5秒钟。
  2. 8001上的服务器收到请求,并用requests.get调用8002服务器。请求是urllib3上的包装器,它是socket上的stdlib包装器,默认情况下gevent.monkey.patch_all()对其进行修补(默认为socket=True)。由于采用了猴子修补程序,我期望服务器正在等待响应。
  3. 8002服务器接收到/sleep/5请求,休眠5秒钟,然后做出响应。因为它是线程服务器,所以可以同时发生多个睡眠。

在非猴子补丁情况下,我希望第一个/slowreq请求花费5秒,第二个请求花费10秒,这就是我所看到的。

但是,在采用猴子补丁的情况下,我希望8001服务器不会再因requests.get调用而阻塞,因此两个请求都将花费5秒钟。不会发生这种情况,其行为与非猴子修补情况相同。

因此,我的问题是:猴子修补有什么作用?我如何利用它的好处?

0 个答案:

没有答案