【问题标题】:Performance Decrease When Using Nginx as Reverse Proxy for Sanic + Gunicorn使用 Nginx 作为 Sanic + Gunicorn 的反向代理时性能下降
【发布时间】:2019-06-24 13:48:17
【问题描述】:

我刚刚开始学习 Sanic 框架,因为它的基准测试速度很快。我制作了一个简单的 hello world API,然后将它与 Gunicorn 连接起来。性能相当不错,但是当我将它与 Nginx 结合时,它变得非常糟糕。我发现带有 Nginx 的 Gunicorn 进程被限制为每个进程的 1% - 4% CPU 资源。如果没有 Nginx,Gunicorn 可以达到每个进程的 10%。我以为是因为 Nginx 配置错误。谁能给我一些建议?

服务器信息:

OS: Ubuntu 18.04    
Python version: 3.7.2    
Sanic version: 18.12.0    
Processor: i3-4130

Sanic + Gunicorn 性能:

wrk -t8 -c1000 -d60s --timeout 2s http://127.0.0.1:8080/
Running 1m test @ http://127.0.0.1:8080/
  8 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    29.54ms   15.13ms 175.77ms   71.23%
    Req/Sec     4.32k     1.29k   19.46k    64.77%
  2060010 requests in 1.00m, 249.50MB read
Requests/sec:  34281.64
Transfer/sec:      4.15MB

Sanic + Gunicorn + Nginx 性能:

wrk -t8 -c1000 -d60s --timeout 2s http://127.0.0.1:8081/
Running 1m test @ http://127.0.0.1:8081/
  8 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   364.78ms  271.20ms   1.39s    67.53%
    Req/Sec   370.88    251.66     3.52k    87.12%
  177223 requests in 1.00m, 30.42MB read
Requests/sec:   2948.79
Transfer/sec:    518.25KB

Sanic 应用:

from sanic import Sanic
from sanic.response import json


app = Sanic()
app.config.ACCESS_LOG = False

@app.route("/")
async def test(request):
    return json({"hello": "world"})

Gunicorn 命令:

gunicorn --bind 127.0.0.1:8080 --workers 8 --threads 4 app:app --worker-class sanic.worker.GunicornWorker --name SanicHelloWorld

全局 Nginx 配置:

worker_processes 8;
worker_rlimit_nofile 400000;
thread_pool sanic_thread_pool threads=32 max_queue=65536;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    multi_accept on;
    worker_connections 25000;
    use epoll;
    accept_mutex off;
}

http {
    access_log off;
    sendfile on;
    sendfile_max_chunk 512k;
    tcp_nopush on;
    tcp_nodelay on;
    server_names_hash_bucket_size 64;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    upstream sanic-test {
        server 127.0.0.1:8080;
    }
}

Sanic + Gunicorn 的 Nginx 配置:

server {
    listen 8081;
    listen [::]:8081;

    server_name sanic-test.com www.sanic-test.com;

    location / {
        aio threads=sanic_thread_pool;
        proxy_pass http://127.0.0.1:8080;
    }
}

【问题讨论】:

  • 关于如何调整 nginx 以获得更好的性能的文章有数百篇,到目前为止,您研究和尝试了什么?你的结果是什么?
  • @Fian 我尝试增加超时,调整工作人员数量,最大连接数,甚至启用线程池。他们都只做了很小的改变。当我查看 Ubuntu 的任务管理器时,它显示 Gunicorn 进程在 Nginx 下的 CPU 使用率非常低。
  • Nginx may be buffering requests/responses to files,文件IO慢。检查您的情况是否发生这种情况。

标签: python nginx reverse-proxy gunicorn sanic


【解决方案1】:

这可能是因为http://nginx.org/r/proxy_buffering 默认设置为on,例如,当您使用http://nginx.org/r/proxy_pass 时。

通常,nginx 应该为您的后端控制 背压,因此,缓冲非常有意义,因为您不希望真正的后端受制于 Slowloris em> 攻击向量。同样,您应该进行缓存并限制与 nginx 背后的真实后端的连接数量,因此,您将所有内容设置为最大值但未能禁用缓冲的测试在现实世界场景中只是一个不切实际的条件,因此,您得到的指标数据非常差。

如果您只是想查看通过简单地向 HTTP 堆栈添加另一层对性能的影响,您应该在使用 proxy_pass 时设置 proxy_buffering off;。否则,测试应该更真实:您的真实后端每秒处理的请求不应超过http://nginx.org/r/proxy_temp_path 指定的存储设备的 IO 参数。

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 2017-07-17
    • 2013-06-04
    • 2021-01-29
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多