首页 文章

http在现代时代保持活力

提问于
浏览
91

所以根据haproxy作者,谁知道关于http的一两件事:

发明Keep-alive是为了在CPU速度慢100倍时降低服务器上的CPU使用率 . 但是没有说的是,持久连接消耗大量内存,而除了打开它们的客户端之外,任何人都无法使用 . 今天在2009年,CPU非常便宜,根据架构或价格,内存仍然限制在几千兆字节 . 如果一个站点需要保持活着,那么就存在一个真正的问题 . 高负载站点通常会禁用keep-alive以支持最大数量的并发客户端 . 没有保持活动的真正缺点是获取对象的延迟略有增加 . 浏览器将非keepalive站点上的并发连接数加倍,以弥补这一点 .

(来自http://haproxy.1wt.eu/

这符合其他人的经验吗?即没有保持活力 - 结果现在几乎不值得注意? (它可能值得注意的是,使用websockets等 - 无论如何,无论保持活动状态如何,连接都保持“开放” - 对于响应速度非常快的应用程序) . 对于远离服务器的人来说效果是否更大 - 或者在加载页面时是否有许多工件要从同一主机加载? (我认为像CSS,图像和JS这样的东西越来越多地来自缓存友好的CDN) .

思考?

(不确定这是否是serverfault.com的事情,但我不会发帖,直到有人告诉我把它移到那里) .

4 回答

  • 2

    嘿,因为我是这个引文的作者,我会回复:-)

    大型网站上存在两个大问题:并发连接和延迟 . 并发连接是由需要很长时间才能下载内容的慢速客户端和空闲连接状态引起的 . 这些空闲连接状态是由连接重用来获取多个对象引起的,称为保持活动,这会因延迟而进一步增加 . 当客户端非常靠近服务器时,它可以大量使用连接并确保它几乎不会空闲 . 然而,当序列结束时,没有人关心快速关闭通道,并且连接长时间保持打开和未使用状态 . 这就是为什么许多人建议使用非常低的保持活动超时的原因 . 在像Apache这样的服务器上,你可以设置的最低超时是一秒,并且通常要承受很高的负载:如果你面前有20000个客户端并且他们每秒平均获取一个对象,那么你将会永久 Build 了20000个连接 . 像Apache这样的通用服务器上的20000个并发连接是巨大的,需要32到64 GB的RAM,具体取决于加载的模块,即使添加RAM,你也可能不希望更高 . 实际上,对于20000个客户端,您甚至可以在服务器上看到40000到60000个并发连接,因为如果有多个要提取的对象,浏览器将尝试设置2到3个连接 .

    如果在每个对象之后关闭连接,则并发连接数将急剧下降 . 实际上,它将下降一个因子,该因子对应于在对象之间按时间下载对象的平均时间 . 如果您需要50毫秒来下载一个对象(一个微型照片,一个按钮等...),并且您每秒平均下载一个对象,如上所述,那么每个客户端只有0.05个连接,这只是1000 20000个客户端的并发连接 .

    现在 Build 新连接的时间很重要 . 远程远程客户端将遇到令人不快的延迟 . 过去,在禁用keep-alive时,浏览器过去常常使用大量并发连接 . 我记得MSIE上有4个,Netscape上有8个 . 这实际上将平均每个对象的延迟除以这么多 . 现在到处都存在keep-alive,我们再也看不到那么高的数字,因为这样做会进一步增加远程服务器的负载,浏览器会负责保护互联网的基础设施 .

    这意味着,对于今天的浏览器,使非保持活动的服务与保持活动的服务一样响应更加困难 . 此外,某些浏览器(例如:Opera)使用启发式方法尝试使用管道连接 . 流水线操作是一种使用keep-alive的有效方法,因为它几乎可以通过发送多个请求而无需等待响应来消除延迟 . 我在一张包含100张小照片的页面上尝试过它,第一次访问速度大约是没有保持活动状态的两倍,但是下一次访问速度大约是其快8倍,因为响应速度很快是如此之小,只有延迟计数(只有“304”响应) .

    我想说理想情况下我们应该在浏览器中设置一些可调参数,以使它们在获取的对象之间保持连接,并在页面完成时立即删除它 . 但不幸的是,我们没有看到这一点 .

    出于这个原因,一些需要在正面安装Apache等通用服务器并且必须支持大量客户端的站点通常必须禁用keep-alive . 为了强制浏览器增加连接数,他们使用多个域名,以便可以并行化下载 . 在密集使用SSL的网站上尤其有问题,因为连接设置甚至更高,因为还有一次往返 .

    现在更常见的是这类网站更喜欢安装光前端,如haproxy或nginx,它们可以处理数十到数十万个并发连接,它们可以在客户端保持活动状态,并在阿帕奇方面 . 在这方面, Build 连接的成本在CPU方面几乎为零,并且在时间方面根本不明显 . 这样就可以提供两全其美的优势:由于保持活动而导致的低延迟,客户端的超时时间非常短,服务器端的连接数也很少 . 每个人都很开心 :-)

    一些商业产品通过重用前端负载 balancer 器和服务器之间的连接以及通过它们多路复用所有客户端连接来进一步改善这一点 . 当服务器靠近LB时,增益并不比以前的解决方案高很多,但通常需要对应用程序进行调整,以确保由于多个用户之间意外共享连接而不存在用户之间会话交叉的风险 . 从理论上讲,这绝不会发生 . 现实有很大不同:-)

  • 138

    自写这篇文章以来(并在stackoverflow上发布),我们现在拥有nginx这样的服务器,这些服务器越来越受欢迎 .

    例如,nginx可以在一个进程中保持打开的10,000个保持活动连接,只有2.5 MB(兆字节)的RAM . 实际上,很容易用很少的RAM保持打开数千个连接,并且你将遇到的唯一限制是其他限制,例如打开文件句柄或TCP连接的数量 .

    Keep-alive was a problem not because of any problem with the keep-alive spec itself but because of Apache's process-based scaling model and of keep-alives hacked into a server whose architecture wasn't designed to accommodate it.

    特别有问题的是Apache Prefork mod_php keep-alives . 这是一个模型,其中每个连接将继续占用PHP进程占用的所有RAM,即使它完全空闲并且仅作为保持活动保持打开状态 . 这不可扩展 . 但服务器不必以这种方式设计 - 服务器需要在一个单独的进程中保持每个保持活动连接没有特别的原因(特别是当每个这样的进程都有一个完整的PHP解释器时) . PHP-FPM和基于事件的服务器处理模型(例如nginx中的服务器处理模型)可以优雅地解决问题 .

    Update 2015:

    SPDY和HTTP / 2用更好的东西取代HTTP的保持活动功能:不仅能够保持连接并在其上发出多个请求和响应,而且能够多路复用,因此响应可以按任何顺序发送并行,而不仅仅是按照他们的要求 . 这可以防止缓慢响应阻止更快的响应,并消除了浏览器保持打开到单个服务器的多个并行连接的诱惑 . 这些技术进一步突出了mod_php方法的不足之处,以及像基于事件(或至少是多线程)的Web服务器之类的东西的好处,它们与PHP-FPM分开耦合 .

  • 2

    我的理解是它与CPU没有多大关系,而是在向世界另一端重复插座的延迟 . 即使你有无限的带宽,连接延迟也会减慢整个过程 . 如果您的页面有数十个对象,则放大 . 即使持久连接有一个请求/响应延迟,但是当你平均有2个套接字时,它会减少,一个应该是流数据,而另一个可能是阻塞 . 此外,在让您写入套接字之前,路由器永远不会假设套接字连接 . 它需要完整的往返握手 . 再说一遍,我不是自称是专家,但这就是我一直看到它的方式 . 真正酷的是完全ASYNC协议(不,不是完全生病的协议) .

  • 22

    如果你使用“原始拉动”CDN,很长时间的保持活动会很有用例如CloudFront或CloudFlare . 事实上,即使您提供的是完全动态的内容,这也可能比没有CDN更快 .

    如果您长期保持活力,以便每个PoP基本上与您的服务器 Build 永久连接,那么当用户第一次访问您的站点时,他们可以使用本地PoP进行快速TCP握手,而不是与您进行慢速握手 . (光本身需要大约100ms才能通过光纤到达世界的一半, Build TCP连接需要来回传递三个数据包.SSL requires three round-trips . )

相关问题