Cloud-init将Gunicorn流量限制为只有少数几个工人。为什么?

时间:2019-06-25 23:07:07

标签: azure ubuntu flask azure-virtual-machine cloud-init

我正在Ubuntu VM上的Gunicorn后面运行Python Flask应用。 Ubuntu VM托管在Azure中,我正在使用cloud-init脚本来安装应用程序,并在VM实例化时启动Gunicorn。

Gunicorn启动时有8个工作程序(对于具有4个vCPU的虚拟机,建议使用)。但是,在VM初始化之后,我的VM吞吐量立即被限制为每秒大约100个请求。

如果我杀死了由cloud-init启动的8个Gunicorn工作程序,并以超级用户身份再次手动启动Gunicorn(又有8个工作程序),那么吞吐量将跃升至每秒约900个请求。

我无法说出cloud-init启动的Gunicorn进程和超级用户启动的Gunicorn进程之间的区别,只是它们在负载下表现出不同的行为。

下面是top的屏幕快照,当VM刚初始化且处于压力状态时:

enter image description here

这是我杀死Gunicorn工作人员并以超级用户身份重新启动他们后的top的屏幕截图:

enter image description here

您可以看到,对于使用cloud-init生成的工作程序,似乎只有几个进程正在获得任何负载,而负载却在超级用户工作程序中平均分配。

下面,我将比较cloud-init和超级用户worker的ps的输出。

cloud-init:

enter image description here

超级用户:

enter image description here

ps的输出表明,cloud-init工作线程确实分布在所有4个vCPU上。我想知道为什么他们表现得好像只有少数人在获得流量。

这是我的cloud-init.txt的内容:

#cloud-config
package_upgrade: true
package_update: true
packages:
  - python3-pip
runcmd:
  - sudo -H pip3 install -U pipenv
  - cd /home/azureuser
  - git clone https://github.com/[user]/[repo].git
  - cd /home/azureuser/serve-stateful
  - pipenv install
  - pipenv run gunicorn -w 8 --bind "$(hostname -I):8034" gunicorn_server:app

1 个答案:

答案 0 :(得分:0)

通过在我的gunicorn启动命令中添加守护程序,用户和组标志来解决此问题:

pipenv run gunicorn -w 8 --bind "$(hostname -I):8034" gunicorn_server:app --user root --group root --daemon

不确定100%的细节,但是我认为问题在于,当未在守护程序模式下启动时,枪杀工人仍保留stdio继承:http://docs.gunicorn.org/en/stable/settings.html#enable-stdio-inheritance向stdio写入所有内容可能会限制性能。

有趣的是,现在每秒的请求进一步增加到每秒1368,因为即使是我在上面的问题中产生的超级用户工人也正在写信给stdio。