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

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

运行ab基准testing ,我能够通过EC2 t2.small实例在清漆层(通过HTTP)实现30k +请求/秒。 然而,当我通过NGINX(HTTPS)运行testing时,我只能够推送160个请求/秒(来自公共networking的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; 

@ domain.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的基准

INTERNAL => @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)

INTERNAL => @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的基准

INTERNAL => @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的基准

INTERNAL => @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 

那么从你提供的信息(还没有提供),我只能猜测。 但从实例types来看(t2有基于票证的性能,当出现票据时,大约有20%的核心;这不是一个好的基准testing实例)和使用ab进行testing(当你写它作为“ABtesting”,首先想到的是这个 )我会说你的performance是非常符合预期的。

当启动SSL或TLS会话时,性能最密集的任务不是数据encryption/解密,而是密钥交换。 由于ab不使用SSL会话caching,密钥交换必须在每个连接上完成。

根据实际使用的密码/ kex / auth套件(不能说,没有提供ab输出),这可能是相当多的CPU的工作。 而且由于两端都在同一台机器上,所以每个连接的CPU需求翻倍(这是一个简化,但在这里足够好)。

在现实世界中使用,保持活力可能会帮助你获得更好的性能(取决于客户端,普通浏览器使用它;尝试ab -k )。 而且你会从SSL会话caching中获得更好的性能(再次取决于客户端,普通浏览器支持它)。

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

仅供参考,您可以参阅英特尔的这篇论文 。 他们比较高度优化的机器(和一些优化的软件)的性能。 考虑一下你的计算能力不足1/30(如果你没有出票的话,可能会低至1/150)。

但是,如果您需要高性能的SSL,则可能需要考虑使用Amazon ELB为您执行SSL终止,因为您已经在EC2上了。

编辑:例如Apache JMeter使用ssl上下文caching。 httperf也是如此。 我发现特别是JMeter擅长模拟真实的负载。 但是对于这种会话caching的httperf方式可能效果最好。

没有看到-k任何区别可能是因为它还没有被使用。 取决于并发设置和(至less在我的机器上)它似乎也取决于url。 如果我使用指向URL中多个IP的域名(不要问我为什么),它不会使用keepalive。

根据你对大规模的看法,但我不希望在这个相当小的实例中每秒爆发超过500个连接,并且不超过250cps。

比较清漆明文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正在做什么)是一样容易得到。 你parsing标题,你发现内存中的内容,你吐出来。 而清漆擅长这一点。

build立encryption连接是完全不同的级别。 所以一旦添加nginx,就必须进行SSL握手(密钥交换,authentication)和encryption,这需要更多的资源。 然后它parsing标题。 然后它必须创build另一个TCP连接到清漆。

同样,在前面提到的英特尔论文中 ,他们有28个内核,并对OpenSSL进行了一些调整,以达到38k HTTPS cps(略高于Varnish性能)。 你有一个核心的五分之一左右,并受到你的虚拟邻居的影响。

引用Amazon EC2实例列表 :

例如,一个t2.small实例以12个CPU Credits每小时的速率连续获得信用。 此function提供了相当于CPU核心20%的基准性能。

还有另一篇来自nginx的文章 :

结果总结单个虚拟化英特尔内核通常可以使用现代密码密码,每秒执行多达350次完整的2048位SSL握手操作。 这相当于每个核心每秒数百个新用户。

所以事实certificate,AB基准没有正确执行HTTPStesting。 当通过HTTPS在内部(通过nginx)运行ab而没有反向代理时,我能够产生7000请求/秒,但是一旦代理被启用,请求就下降到160 / s。 事实certificate,ab的keepalivefunction不适用于HTTPS +反向代理,必须是一个错误。

我通过cURL生成了我自己的testing,并能够达到预期的结果:500-600请求/秒。 我追加了保持活动的头,并将结果发送到/ dev / null。 用10个并发cURL进程启动100个微型实例,请求500个URL。

清漆请求https