所以根据haproxy作者,谁知道一两件关于http:
发明了Keep-alive以减少CPU CPU为100时在服务器上的使用情况 时间慢。但是没有说的是 持久连接消耗了一个 大量的内存虽然不可用 除了客户以外的任何人 打开他们。今天在2009年,CPU是 非常便宜,内存仍然有限 架构为几千兆字节 或价格。如果网站需要 保持活力,存在一个真正的问题。 高负载的网站经常禁用 保持活力以支持最大值 同时客户的数量。该 没有保持活力的真正缺点 是一个稍微增加的延迟 获取对象。浏览器翻倍 on并发连接数 非keepalive网站,以弥补 此
这是否符合其他人的经验?即没有保持活力 - 结果现在几乎不值得注意? (它可能值得注意的是,使用websockets等 - 无论如何,无论保持活动状态如何,连接都保持“开放” - 对于响应速度非常快的应用程序)。 对于远离服务器的人来说效果是否更大 - 或者在加载页面时是否有许多工件要从同一主机加载? (我认为像CSS,图像和JS这样的东西越来越多地来自缓存友好的CDN)。
思考?
(不确定这是否是serverfault.com的事情,但我不会发帖,直到有人告诉我把它移到那里)。
答案 0 :(得分:139)
嘿,因为我是这个引文的作者,我会回答: - )
大型网站上存在两个大问题:并发连接和延迟。并发连接是由需要很长时间才能下载内容的慢速客户端和空闲连接状态引起的。这些空闲连接状态是由连接重用来获取多个对象引起的,称为保持活动,这会因延迟而进一步增加。当客户端非常靠近服务器时,它可以大量使用连接并确保它几乎不会空闲。然而,当序列结束时,没有人关心快速关闭通道,并且连接长时间保持打开和未使用状态。这就是为什么许多人建议使用非常低的保持活动超时的原因。在像Apache这样的服务器上,你可以设置的最低超时是一秒,并且通常要承受很高的负载:如果你面前有20000个客户端并且他们每秒平均获取一个对象,那么你将会永久建立了20000个连接。像Apache这样的通用服务器上的20000个并发连接是巨大的,需要32到64 GB的RAM,具体取决于加载的模块,即使添加RAM,你也可能不希望更高。实际上,对于20000个客户端,您甚至可以在服务器上看到40000到60000个并发连接,因为如果有很多要提取的对象,浏览器将尝试设置2到3个连接。
如果在每个对象之后关闭连接,则并发连接数将急剧下降。实际上,它将下降一个因子,该因子对应于在对象之间按时间下载对象的平均时间。如果您需要50毫秒来下载一个对象(一个微型照片,一个按钮等...),并且您每秒平均下载一个对象,如上所述,那么每个客户端只有0.05个连接,这只是1000 20000个客户端的并发连接。
现在建立新连接的时间很重要。远程远程客户端将遇到令人不快的延迟。过去,在禁用keep-alive时,浏览器过去常常使用大量并发连接。我记得MSIE上有4个,Netscape上有8个。这实际上将平均每个对象的延迟除以这么多。现在到处都存在keep-alive,我们再也看不到那么高的数字,因为这样做会进一步增加远程服务器的负载,浏览器会负责保护互联网的基础设施。
这意味着,对于今天的浏览器来说,让非保持活动的服务与保持活跃的服务一样响应更加困难。此外,某些浏览器(例如:Opera)使用启发式方法尝试使用管道连接。流水线操作是一种使用keep-alive的有效方法,因为它几乎可以通过发送多个请求而无需等待响应来消除延迟。我在一张包含100张小照片的页面上尝试过它,第一次访问速度大约是没有保持活动状态的两倍,但是下一次访问速度大约是其快8倍,因为响应非常小,只有延迟计数(仅限“304”回复)。
我想说理想情况下我们应该在浏览器中设置一些可调参数,以使它们在获取的对象之间保持连接,并在页面完成时立即删除它。但不幸的是,我们没有看到这一点。
出于这个原因,一些需要在正面安装Apache等通用服务器并且必须支持大量客户端的站点通常必须禁用keep-alive。为了强制浏览器增加连接数,他们使用多个域名,以便可以并行化下载。在密集使用SSL的网站上尤其有问题,因为连接设置更高,因为还有一次额外的往返。
现在更常见的是这类网站更喜欢安装光前端,例如haproxy或nginx,它们处理数十到数十万个并发连接没有问题,它们可以在客户端保持活动状态,并禁用它在Apache方面。在这方面,建立连接的成本在CPU方面几乎为零,并且在时间方面根本不明显。这样就可以提供两全其美的优势:由于保持活动而导致的低延迟,客户端的超时时间非常短,服务器端的连接数也很少。每个人都很高兴: - )
一些商业产品通过重用前端负载平衡器和服务器之间的连接以及通过它们复用所有客户端连接来进一步改进这一点。当服务器靠近LB时,增益并不比以前的解决方案高很多,但通常需要对应用程序进行调整,以确保由于多个用户之间意外共享连接而不存在用户之间会话交叉的风险。从理论上讲,这绝不会发生。现实有很大不同: - )
答案 1 :(得分:22)
自写这篇文章以来(并在stackoverflow上发布),我们现在拥有nginx这样的服务器,这些服务器越来越受欢迎。
例如,nginx可以在一个进程中保持打开的10,000个保持活动连接,只有2.5 MB(兆字节)的RAM。实际上,很容易用很少的RAM保持打开数千个连接,并且你将遇到的唯一限制是其他限制,例如打开文件句柄或TCP连接的数量。保持活动是一个问题,不是因为保持活动规范本身存在任何问题,而是因为Apache的基于流程的扩展模型和保持活动被黑客入侵到其架构不适合的服务器它强>
特别有问题的是Apache Prefork + mod_php + keep-alives。这是一个模型,其中每个连接将继续占用PHP进程占用的所有RAM,即使它完全空闲并且仅作为保持活动保持打开状态。这不可扩展。但服务器不必以这种方式设计 - 服务器需要在一个单独的进程中保持每个保持活动连接没有特别的原因(特别是当每个这样的进程都有一个完整的PHP解释器时)。 PHP-FPM和基于事件的服务器处理模型(如nginx中的模型)可以优雅地解决问题。
更新2015:
SPDY和HTTP / 2用更好的东西取代HTTP的保持活动功能:不仅能够保持连接并通过它发出多个请求和响应,而且能够多路复用,因此可以发送响应以任何顺序,并行,而不是按照它们被要求的顺序。这可以防止缓慢响应阻止更快的响应,并消除了浏览器保持打开到单个服务器的多个并行连接的诱惑。这些技术进一步突出了mod_php方法的不足之处,以及像基于事件(或至少是多线程)的Web服务器之类的东西的好处,它们与PHP-FPM分开耦合。
答案 2 :(得分:2)
我的理解是,它与CPU没什么关系,但是在向世界的另一端打开重复套接字的延迟。即使你有无限的带宽,连接延迟也会减慢整个过程。如果您的页面有数十个对象,则放大。即使是持久连接也有一个请求/响应延迟,但是当你平均有2个套接字时它会减少,一个应该是流数据而另一个应该阻塞。此外,路由器永远不会假设套接字连接,然后让您写入它。它需要完整的往返握手。再说一遍,我不是自称是专家,但这就是我一直看到它的方式。真正酷的是完全ASYNC协议(不,不是完全生病的协议)。
答案 3 :(得分:2)
如果您正在使用“原始拉动”CDN(如CloudFront或CloudFlare),则很长时间保持活动非常有用。事实上,即使您正在提供完全动态的内容,这也可能比没有CDN更快。
如果您长期保持活力,以便每个PoP基本上与您的服务器建立永久连接,那么当用户第一次访问您的站点时,他们可以使用本地PoP进行快速TCP握手,而不是与您进行慢速握手。 (光本身需要大约100ms才能通过光纤到达世界的一半,建立TCP连接需要来回传递三个数据包。SSL requires three round-trips。)