我们发出大量 HTTP 请求。最近,我们开始考虑在操作系统级别进行优化,以便从单台机器发出更多请求。
为了检查操作系统的性能,我创建了一个小型基准测试来比较不同机器上的情况。基准测试使用curl -w
如下:
#!/bin/bash
for (( ; ; ))
do
curl $URL -o /dev/null -s -w "SIZE: %{size_download} SPEED: %{speed_download} LOOKUP: %{time_namelookup} CONNECT: %{time_connect} START: %{time_starttransfer} TOTAL: %{time_total}\n"
done
现在我针对 1 个 URL 运行它。结果如下:从我的本地开发机器(通过 Fiber 连接):
SPEED (b/sec) LOOKUP CONNECT START TOTAL
13,331.2481 0.0022 0.0228 0.2163 0.2175
在我们的一台生产服务器(使用 XEN 虚拟化)上,结果略有不同:
SPEED (b/sec) LOOKUP CONNECT START TOTAL
22,764.7700 0.0093 0.0455 0.1318 0.1334
在另一台不相关的服务器上,没有 XEN 虚拟化(不同的数据中心,不同的大陆,距离资源较远)
SPEED (b/sec) LOOKUP CONNECT START TOTAL
32,821.3569 0.0004 0.0080 0.1608 0.1672
如您所见,我们生产服务器上的性能远不能令人满意。数据传输速率比我的本地笔记本电脑快,但延迟正在扼杀我们。由于我们获取的 HTTP 资源大小相当小,因此我们需要来优化这个延迟。
知道从哪儿开始吗?
更新:这与扩展 Web 服务器无关。而是与扩展 Web 请求有关。
答案1
这是一个经过充分研究的问题(“高性能网络爬行”),有大量可用的研究:http://scholar.google.com/scholar?q=web+crawling+performance...是的,我作弊了,但老实说,你应该先看一下文献。
根据我过去构建此类系统的经验:你无法超越光速,所以无论如何你都会遇到这种情况。你可以做的是优化安排资源获取的方式和时间。例如,你可以优化子系统来处理问题的部分内容 - 例如 DNS 解析。你可以预先解析名称并直接连接到 IP 地址(只需添加正确的主机标头)。之后,你将不得不承担 TCP 连接成本,没有办法绕过它。也就是说,如果你对同一主机有多个请求,那么你可以利用它在现有连接上序列化多个请求:这有助于摊销 TCP/TLS 握手成本并为你提供更好的端到端性能。从那里,你必须向上移动协议阶梯:有时你可以跟踪重定向链并记住最后的位置以跳过将来的额外重定向(只需有一个后备)。事实上,这同样适用于 DNS。你可以实施一个乐观策略并直接连接到 IP,然后在失败时使用后备。对于 TLS,您可以存储会话票证和其他元数据以获得更快的重新连接(也就是说,假设您足够频繁地重新连接)。
总结:我在这里没有添加任何新内容,所有上述技巧(以及更多)都已在现有研究中涵盖。喝杯咖啡,花点时间阅读现有论文!
答案2
我不知道您的 http 请求发往何处,但您可以查看相关的网络服务器是否支持 SPDY。
由 Google 开发,快闪记忆体尝试通过管道传输多个 https 请求,以获得更大的吞吐量和更低的延迟。
我也赞同上述有关 DNS 优化的任何建议。您确实需要设置缓存转发 DNS 来加快速度。如果您可以控制 Web 服务器的 TTL,那么在您觉得合适的范围内增加 TTL 是值得的。