我正在测试将 HTTPS 添加到我的小型网站,由于我的配置允许通过 HTTP 或 HTTPS 访问我的网站,因此我决定使用 ab(例如ab -n 1000 -c 5 http://{mywebsite}/{resource}
vs ab -n 1000 -c 5 https://{mywebsite}/{resource}
)对其进行基准测试。令我惊讶的是,我发现每个百分位的每个请求对于 HTTPS 所花费的时间大约是其两倍。
我使用非常便宜的机器(具体来说是 AWS t2.micro)来托管我的 Web 应用程序(java/jetty)和执行 gzip 和 SSL 的 nginx,因此,我的第一个想法是,对于大型网站来说,这不应该是真的,而且我没有足够的 CPU 能力。此外,众所周知,这些机器的网络性能很差。
然后出于好奇,我尝试对一些在 HTTP 和 HTTPS 上都提供某些内容的网站运行相同的 ab 行(例如https://www.aol.com/robots.txt对比http://www.aol.com/robots.txt和https://www.fedex.com/robots.txt对比http://www.fedex.com/robots.txt举几个例子)。你猜怎么着?我也看到了同样的模式——HTTPS 的每个百分位数大约是通过 HTTP 提供的相同资源的相应百分位数的两倍或三倍。
我认为我的提供商应该受到指责,但我尝试从其中一个 AWS 盒子运行那些 ab 基准测试,我发现延迟有所改善,但模式仍然是相同的:对于我和上述大牌网站来说,HTTP 请求的速度至少是 HTTPS 的两倍。
我想知道这是什么原因造成的?我尝试对 localhost 运行 ab(显然禁用了 HTTPS 证书检查),差异并不大(我认为约为 10-15%)。
如果有人看到这篇文章,我会很高兴知道上述开销的更多性质。我不是网络工程师,所以我几乎不了解 TLS 握手是否是导致延迟增加的唯一因素。
还有什么可能导致这些结果?
更新:
正如许多人指出的那样,TLS 握手可能是根本原因。并且对于上述示例,当执行请求的时间可以忽略不计时(例如提供静态内容),TLS 握手就是根本原因。
我刚刚看到一个选项,它清楚地显示了这一点,它是-k
一个启用连接重用的选项。启用此选项后,HTTPS 的总体成本比不重用连接时要小得多。
答案1
加密会产生一定程度的开销,这取决于:
- 硬件
- 服务器
- 动态内容与静态内容的比例
- 客户的距离
- 会话长度
- 缓存
具有大量动态内容的服务器受 HTTPS 的影响较小,因为与内容生成时间相比,加密所花费的时间(SSL 开销)微不足道。 大量提供可轻松缓存在内存中的少量静态页面的服务器会因降低吞吐量而承受更高的开销。 SSL 握手是 HTTPS 的主要成本。 这就是“会话长度”和“缓存”如此重要的原因。 较长的会话意味着在会话开始时会产生握手成本,但后续请求的开销相对较低。
缓存可以分几个步骤进行,从大型代理服务器到单个浏览器缓存。通常,HTTPS 内容不会缓存在共享缓存中。许多浏览器会为当前会话缓存 HTTPS 内容,并且通常会跨会话缓存。不缓存或较少缓存的影响意味着客户端将更频繁地检索相同的内容。这会导致更多的请求和带宽来为相同数量的用户提供服务。
通过 HTTPS 发出大量短请求会比 HTTP 慢一点,但如果您在单个请求中传输大量数据,差异将微不足道。但是,keepalive 是 HTTP/1.1 中的默认行为,它将进行一次握手,然后可以处理同一连接上的大量请求。这对 HTTPS 来说是一个显著的差异。