python 无法将Gunicorn/Flask HelloWorld缩放超过125 RPS

6za6bjd0  于 2023-01-16  发布在  Python
关注(0)|答案(2)|浏览(124)

我有一个 flask 应用程序,我一直无法在本地扩展超过125 RPS。这是一个简单的“你好世界”,如下所示。
我正在使用Locust.io负载测试工具。我已经将相同的负载测试指向本地Golang hello world,并且能够进入1000个RPS。恕我直言,这排除了我的Locust和OS配置作为潜在瓶颈的可能性。
我使用17个工人,因为我的机器有8个内核(Gunicorn文档推荐(2*CPU)+1
据我所知,在Gunicorn中使用gevent工作者类型应该可以让我达到1000的RPS,就像Golang一样。这是一个正确的假设吗?或者我错过了一些关键的东西?
缩写代码:

app = Flask(__name__)

@app.route('/')
def hello():
    return 'hello world!'

Gunicorn配置:

gunicorn -k gevent -w 17  --worker-connections 100000 app:app

蝗虫负载测试结果。每个“用户”每4s x1c 0d1x获取“/”一次

67up9zun

67up9zun1#

作者的回答如下:https://github.com/benoitc/gunicorn/issues/305
经过又一周的调试,我想通了!原来还有一个额外的工作者类型gevent_pywsgi。使用这个工作者类型将吞吐量增加了大约10倍,达到了我认为可以接受的水平。
我的测试显示sync worker和gevent worker在性能上没有差别,所以我仍然不确定那里发生了什么,或者gevent worker类型的意图是什么。

sulc1iza

sulc1iza2#

我也在相同的场景中,在gunicorn中使用sync工人(默认工人类),目标是相同的,即增加RPS。
然后我在gevent(其他选项之一)的帮助下切换到async工人。
我们在gunicorn中使用gevent时(我也是)经常犯的一个错误是仅仅将其用作参数,即--worker-class=gevent
这让整个枪角指挥部看起来像是...

gunicorn --bind=127.0.0.1:5000 --workers=4 --worker-class=gevent wsgi:application

我们都忘了做的是相应地修改flask代码。
我们得修改一下

from flask import Flask

app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return 'hello world!'

变成这样

from gevent import monkey
monkey.patch_all() # monkey patching

from flask import Flask

app = Flask(__name__)
        
@app.route('/')
def hello():
    return 'hello world!'

添加这些行是至关重要的,您将体验到RPS的增量。
在我的情况下,我有
~90 RPS,带20个同步工作器+EC2服务器(计算优化)+本地API命中
~430 RPS,具有8个异步工作进程(gevent)+每个工作进程1个线程+EC2服务器(正常)+本地API命中
~600 RPS,具有8个异步工作进程(gevent)+每个工作进程16个线程+EC2服务器(正常)+本地API命中
~900 RPS,具有8个异步工作进程(gevent)+每个工作进程32个线程+EC2服务器(正常)+本地API命中
在我的例子中,使用这两行代码可以看到RPS急剧增加了10倍(尽管我在后面的测试中使用的是普通的EC2机器)。

相关问题