我正在尝试设置一个非常高性能的 Web 服务器来处理长轮询、WebSocket 等。我有一个运行中的 VM(Rackspace),具有 1GB RAM/4 核。我已经使用(异步)gevent 工作器设置了一个非常简单的 gunicorn“hello world”应用程序。在 gunicorn 前面,我放置了 Nginx 和一个简单的 Gunicorn 代理。使用ab
,Gunicorn 会吐出7700 个请求/秒,其中 Nginx 只做了5000 请求/秒. 这样的性能下降是预料之中的吗?
你好世界:
#!/usr/bin/env python
def application(environ, start_response):
start_response("200 OK", [("Content-type", "text/plain")])
return [ "Hello World!" ]
古尼康:
gunicorn -w8 -k gevent --keep-alive 60 application:application
Nginx(已剥离):
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
upstream app_server {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 8080 default;
keepalive_timeout 5;
root /home/app/app/static;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
}
基准:(结果:nginx TCP,nginx UNIX,gunicorn)
ab -c 32 -n 12000 -k http://localhost:[8000|8080]/
通过 unix 套接字运行 gunicorn 可以获得更高的吞吐量(5500转/秒),但是还是比不上原始 gunicorn 的性能。
答案1
您可以使用以下命令将 gunicorn 的连接超时减少到 0 秒:
http://docs.gunicorn.org/en/latest/settings.html#timeout
您还可以通过以下指令将 keep_alive 用于 proxy_pass 后端: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
请注意,keep alive 指令在较旧的 nginx 版本中不可用
答案2
Nginx 不使用 keepalive 来与后端通信,因此您应该在 gunicorn 中禁用它。此外,我将开始使用 1 个 worker 来测试 nginx,这样它就不会与 gunicorn 争夺空闲的 CPU。如果 worker 连接回收速度不够快,您可能需要增加它们的连接数。
此外,由于 nginx 引入了自身的延迟(尽管很低),因此您永远无法获得与原始 gunicorn 相同的性能。您可以直接使用 gunicorn 为您的应用程序提供服务,并使用另一个域中的 nginx 为您的静态资产提供服务,这具有一些优势,例如 cookie 清洁流量。