NGINX HTTPS 反向代理 - TTFB 速度快但并发性低

NGINX HTTPS 反向代理 - TTFB 速度快但并发性低

我有一个运行的应用程序:NGINX(SSL)=> VARNISH(CACHE)=> APACHE/PHP。

跑步ab 基准,我能够通过 EC2 t2.small 实例在 varnish 层(通过 HTTP)上实现每秒 30k+ 请求。但是,当我通过 NGINX(HTTPS)运行测试时,我只能推送每秒 160 个请求(来自公共网络的 TTFB 平均为 43ms)。

@nginx.conf

user  nginx;
worker_processes  auto;

worker_rlimit_nofile 65535;

error_log  /var/log/nginx/error.log;

pid        /var/run/nginx.pid;


events {
    worker_connections  16024;
        multi_accept on;
}

在 http 级别:

sendfile        on;
tcp_nopush     on;

keepalive_timeout  10;


ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

@ 域名.conf

server {
        listen 443 ssl;

        server_name xyz.com;
        ssl_certificate /home/st/ssl3/xyz.crt;
        ssl_certificate_key /home/xyz/ssl3/xyz.key;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

        ssl_session_tickets on;

        location / {

                proxy_buffers 8 8k;
                proxy_buffer_size 2k;


            proxy_pass http://127.0.0.1:79;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Port 443;
            proxy_set_header Host $host;

                proxy_redirect off;

        }

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}

以下是 Apache 的基准测试

内部 => @APACHE:

Concurrency Level:      10
Time taken for tests:   0.694 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1002
Keep-Alive requests:    996
Total transferred:      705122 bytes
HTML transferred:       401802 bytes
Requests per second:    1440.93 [#/sec] (mean)
Time per request:       6.940 [ms] (mean)
Time per request:       0.694 [ms] (mean, across all concurrent requests)
Transfer rate: 992.22 [Kbytes/sec] received

这是 Varnish 的基准测试(之前它的运行速度为 20-30k - 耗尽了我的 CPU 周期,平均 ATM 为 4-8k rps)

内部 => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   0.232 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    0
Total transferred:      23439800 bytes
HTML transferred:       23039412 bytes
Requests per second:    4310.16 [#/sec] (mean)
Time per request:       2.320 [ms] (mean)
Time per request:       0.232 [ms] (mean, across all concurrent requests)
Transfer rate:          98661.39 [Kbytes/sec] received

以下是 NGINX 的基准测试HTTP

内部 => @NGINX[HTTP] => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   0.082 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1001
Keep-Alive requests:    1000
Total transferred:      382382 bytes
HTML transferred:       184184 bytes
Requests per second:    12137.98 [#/sec] (mean)
Time per request:       0.824 [ms] (mean)
Time per request:       0.082 [ms] (mean, across all concurrent requests)
Transfer rate:          4532.57 [Kbytes/sec] received

以下是 NGINX 的基准测试HTTPS

内部 => @NGINX[HTTPS=>HTTP] => @VARNISH => @APACHE:

Concurrency Level:      10
Time taken for tests:   7.029 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Non-2xx responses:      1000
Keep-Alive requests:    0
Total transferred:      663000 bytes
HTML transferred:       401000 bytes
Requests per second:    142.27 [#/sec] (mean)
Time per request:       70.288 [ms] (mean)
Time per request:       7.029 [ms] (mean, across all concurrent requests)
Transfer rate:          92.12 [Kbytes/sec] received

答案1

好吧,根据您提供的信息(和未提供的信息),我只能猜测。但从实例类型(t2 具有突发票数性能,当票数用完时,大约占用 20% 的核心;它不是进行基准测试的好实例)和ab测试用途(顺便说一句,当您将其写为“AB 测试”时,首先想到的是)我想说你的表现与预期差不多。

启动 SSL 或 TLS 会话时,最耗性能的任务不是数据加密/解密,而是密钥交换。由于ab不使用 SSL 会话缓存,因此每次连接时都必须进行密钥交换。

根据实际使用的密码/kex/auth 套件(无法判断,未ab提供输出),对于 CPU 来说,这可能是相当多的工作。而且由于两端都在同一台机器上,因此每个连接的 CPU 要求加倍(这是简化,但在这里已经足够了)。

在实际使用中,keep alives 可能会帮助您获得更好的性能(取决于客户端,普通浏览器都使用它;尝试ab -k)。并且您将从您提到的 SSL 会话缓存中获得更好的性能(同样取决于客户端,普通浏览器都支持它)。

还有其他几种方法可以帮助您提高性能。当然,您可以获得更好的硬件。您可以优化密钥大小(取决于应用程序所需的保护级别)——较小的密钥通常更便宜。从不同的机器进行测试可能会或可能不会提高明显的性能。并且获得不同的 OpenSSL 版本或完全不同的 SSL 库也可以提供更好的性能。

仅供参考,你可以看看这张纸由英特尔提供。他们确实在高度优化的机器(和一些优化的软件)上比较性能。假设您可用的计算能力不到其 1/30(如果您没有票,则可能低至 1/150)。

不过,如果您需要高性能 SSL,可能值得考虑使用 Amazon ELB 为您执行 SSL 终止,因为您已经在使用 EC2。

编辑:例如Apache JMeter使用 ssl 上下文缓存。httperf也一样。我发现 JMeter 尤其擅长模拟真实负载。但对于这种 httperf 方式,会话缓存可能效果最好。

看不到任何差异-k可能是因为它仍未使用。取决于并发设置,并且(至少在我的计算机上)它似乎也取决于 URL。如果我使用指向 URL 中多个 IP 的域名,它不会使用 keepalive(不要问我为什么)。

这取决于您对大规模的感知,但我预计在这个相当小的实例上每秒不会突发超过 500 个连接,并且持续连接数不会超过 250 cps。

将 varnish plaintext http 与 nginx ssl 进行比较就像是将梨与苹果进行比较。或者更确切地说,在硬件要求方面将蓝莓与西瓜进行比较。

再次供您参考(注意那条Keep-Alive requests: 100线)。

没有-k

Concurrency Level:      1
Time taken for tests:   0.431 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      399300 bytes
HTML transferred:       381200 bytes
Requests per second:    232.26 [#/sec] (mean)
Time per request:       4.305 [ms] (mean)
Time per request:       4.305 [ms] (mean, across all concurrent requests)
Transfer rate:          905.69 [Kbytes/sec] received

-k

Concurrency Level:      1
Time taken for tests:   0.131 seconds
Complete requests:      100
Failed requests:        0
Keep-Alive requests:    100
Total transferred:      402892 bytes
HTML transferred:       381200 bytes
Requests per second:    762.11 [#/sec] (mean)
Time per request:       1.312 [ms] (mean)
Time per request:       1.312 [ms] (mean, across all concurrent requests)
Transfer rate:          2998.53 [Kbytes/sec] received

编辑 2:好吧,您需要了解,直接从内存提供内容(这就是 Varnish 所做的)是最简单的。您解析标头,在内存中找到内容,然后将其吐出。Varnish 在这方面表现出色。

建立加密连接是完全不同的层次。因此,一旦添加 nginx,它就必须进行 SSL 握手(密钥交换、身份验证)和加密,这需要更多资源。然后它解析标头。然后它必须创建另一个到 Varnish 的 TCP 连接。

再次,在前面提到的英特尔论文,它们有 28 个核心,并对 OpenSSL 进行了一些调整,以执行 38k HTTPS cps(比您的 Varnish 性能略高)。您有大约 1/5 个核心,并且受到虚拟邻居的影响。

引用Amazon EC2 实例列表

例如,t2.small 实例以每小时 12 个 CPU 积分的速度持续接收积分。此功能提供相当于 CPU 核心 20% 的基准性能。

还有另一个来自 nginx 本身:

结果摘要 单个虚拟化 Intel 内核通常可以使用现代加密算法每秒执行多达 350 次完整的 2048 位 SSL 握手操作。这相当于每核每秒为您的服务带来数百名新用户。

相关内容