我们做了很多的HTTP请求。 最近,我们开始考虑在操作系统级别进行优化,以便从一台机器发出更多的请求。
为了检查我们的操作系统的性能,我创build了一个小的基准来比较不同机器上的东西。 基准使用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。 结果如下:从我的本地开发机器(连接光纤):
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服务器。 这是关于缩放networking请求。
这是一个很好研究的问题(“高性能networking爬行”),有大量可用的研究: http : //scholar.google.com/scholar ?q=web+crawling+performance …是的,我是作弊,但老实说,你应该先阅读文献。
根据我以往build立这种系统的经验:你不能轻易击败光速,所以不pipe怎么样,你都会招致这样的结果。 你可以做的是优化如何以及何时安排资源提取。 例如,你可以有优化的子系统来处理部分问题 – 例如DNSparsing。 您可以预先parsing名称并直接连接到IP地址(只需添加正确的主机头)。 之后,你将不得不承担TCP连接成本,没有办法绕过它。 也就是说,如果您对同一个主机有多个请求,那么您可以利用这个请求在现有连接上序列化多个请求:这有助于缓解TCP / TLS握手成本,并为您提供更好的端到端性能。 从那里开始,你必须向上移动协议阶梯:有时你可以跟踪redirect链,并记住最后一个位置,以便在未来跳过额外的redirect(只是有一个后备)。 实际上,同样适用于DNS ..您可以实施乐观策略并直接连接到IP,然后使用回退(如果失败)。 对于TLS,您可以存储会话票据和其他元数据以获得更快的重新连接(也就是说,假设您足够频繁地重新连接)。
tl; dr:我没有在这里添加任何新东西,所有上述提示(以及更多)都包含在可用的研究中。 拿起一杯咖啡,花一些时间阅读现有的文件!
我不知道你的http请求在哪里,但你可以看到问题的networking服务器是否支持SPDY。
SPDY是在Google开发的,旨在传输多个https请求,以获得更高的吞吐量和更低的延迟。
上面还有关于DNS优化的其他build议。 你真的想build立一个caching转发DNS,使事情变得更快。 如果您对networking服务器的TTL有任何控制权,只要您愿意,就可以增加它们。