如何创建非缓存的快速 nginx 反向代理?

如何创建非缓存的快速 nginx 反向代理?

Nginx 应该很快 —— 至少人们这么说。

我无法让 nginx 运行得更快。为了进行基准测试,我使用siege多种配置来模拟高负载。因此,我尝试对单个服务器进行负载平衡(我知道对单个服务器进行负载平衡是相当无用的,但对于测试负载平衡器本身来说,这是有效的)。我已经设置了一个已经优化的 apache 反向代理作为参考。当我尝试从同一个后端服务器获取相同的(非缓存)文件时,我通过 nginx 获得大约 80tps,使用 apache 获得大约 350tps。当然,硬件/操作系统是相同的(当前双核 CPU、2G 内存、Ubuntu Server 16.04)。

我已经尝试更改工作程序、最大连接数、轮询方法、代理缓冲区大小、等待时间和客户端缓冲区。我可以看到系统负载很低,一个 nginx 使用大约 1% 的 CPU,连接将等待大约 5 到 6 秒。因为我想测量反向代理的性能,所以我不想在这个测试中缓存任何东西。

那么问题是:如何优化 nginx 作为非缓存反向代理的性能?

攻城命令示例:siege -c 100 -b -r 100 -v <loadbalancer>/favicon.ico

更新:根据要求进行一些配置。为了使问题符合 serverfault 的要求,请回答有关参数的一般有用信息。

user www-data;
worker_processes 2;
pid /run/nginx.pid;
#thread_pool default threads=1500 max_queue=65536;
worker_rlimit_nofile 40000;

events {
    worker_connections 768;
    #multi_accept on;
    #use epoll;
}

http {

    #aio threads=default;
    #proxy_buffers           32 4m;
    #proxy_busy_buffers_size     25m;
    #proxy_buffer_size 512k;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    access_log /var/log/nginx/access.log combined buffer=1k;
    error_log /var/log/nginx/error.log;

    gzip off;
    # gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    upstream kronos-backend {
        server kronos.example.com;
    }

    server {
        listen 80;
        listen [::]:80;

        ssl_certificate     /etc/ssl/certs/snakeoil.crt;
        ssl_certificate_key /etc/ssl/private/snakeoil.key;

        listen 443 ssl;
        listen [::]:443 ssl;

        keepalive_timeout 60;

        root /var/www/vhosts/default;

        index index.html;

        server_name <name>;

        server_tokens off; # Don't show that nginx is bringing out the website.

        location / {
            proxy_set_header Host            <name>;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_pass http://kronos-backend;

            client_body_buffer_size 1M; # Lets keep all client-sent bodies in memory if less than 1 Megabyte. (Default for amd64: 16K)
            client_max_body_size 10M; # Maximum accepted body is 10M (Default is 1M).
        }
    }
}

我知道这个配置不太干净。但它或多或少显示了我已经尝试过的内容。它源自 Ubuntu 中 nginx 包的默认配置。

连接方式如下:

       +--- apache2 ---+
       |               |
siege -+               +--> some webserver (not of interest)
       |               |
       +--- nginx -----+

因此,只要不涉及缓存,并且使用相同的 URL(在本例中为静态文件)进行测试,通过 nginx 或 apache2 传输的数据就无关紧要。任何 Web 服务器都没有故意激活缓存机制。

apache 中的配置使用 mpm_worker。

ThreadLimit          600
StartServers         4
ServerLimit          11
MinSpareThreads      50
MaxSpareThreads      100
ThreadsPerChild      200
MaxClients           1000
MaxRequestsPerChild  20000

上述围攻命令的示例输出:

$ siege -c 100 -b -r 10 <nginx>/wrapper_2_bg.png
** SIEGE 3.0.5
** Preparing 100 concurrent users for battle.
The server is now under siege..      done.

Transactions:                   1000 hits
Availability:                 100.00 %
Elapsed time:                  11.01 secs
Data transferred:               0.12 MB
Response time:                  0.84 secs
Transaction rate:              90.83 trans/sec
Throughput:                     0.01 MB/sec
Concurrency:                   76.24
Successful transactions:        1000
Failed transactions:               0
Longest transaction:            6.67
Shortest transaction:           0.03


$ siege -c 100 -b -r 10 <apache>/wrapper_2_bg.png
** SIEGE 3.0.5
** Preparing 100 concurrent users for battle.
The server is now under siege..      done.

Transactions:                   1000 hits
Availability:                 100.00 %
Elapsed time:                   3.16 secs
Data transferred:               0.12 MB
Response time:                  0.22 secs
Transaction rate:             316.46 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                   68.95
Successful transactions:        1000
Failed transactions:               0
Longest transaction:            3.06
Shortest transaction:           0.05

答案1

数据包丢失是问题的根源。负载均衡器和后端 Web 服务器之间有一个路由器。路由器似乎不够快,因为在测试时其负载达到 100%。结果就是数据包丢失。

我不知道为什么 apache 似乎能更好地处理这个问题。将负载平衡器移动到与交付 Web 服务器相同的网络,两种方式的性能几乎相同,而且要高得多。

相关内容