我有一个 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获取“/”一次
2条答案
按热度按时间67up9zun1#
作者的回答如下:https://github.com/benoitc/gunicorn/issues/305
经过又一周的调试,我想通了!原来还有一个额外的工作者类型
gevent_pywsgi
。使用这个工作者类型将吞吐量增加了大约10倍,达到了我认为可以接受的水平。我的测试显示
sync
worker和gevent
worker在性能上没有差别,所以我仍然不确定那里发生了什么,或者gevent
worker类型的意图是什么。sulc1iza2#
我也在相同的场景中,在
gunicorn
中使用sync
工人(默认工人类),目标是相同的,即增加RPS。然后我在
gevent
(其他选项之一)的帮助下切换到async
工人。我们在gunicorn中使用gevent时(我也是)经常犯的一个错误是仅仅将其用作参数,即
--worker-class=gevent
。这让整个枪角指挥部看起来像是...
我们都忘了做的是相应地修改flask代码。
我们得修改一下
变成这样
添加这些行是至关重要的,您将体验到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机器)。