我有一个运行的应用程序: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 个核心,并且受到虚拟邻居的影响。
例如,t2.small 实例以每小时 12 个 CPU 积分的速度持续接收积分。此功能提供相当于 CPU 核心 20% 的基准性能。
还有另一个纸来自 nginx 本身:
结果摘要 单个虚拟化 Intel 内核通常可以使用现代加密算法每秒执行多达 350 次完整的 2048 位 SSL 握手操作。这相当于每核每秒为您的服务带来数百名新用户。