为什么我们启用HTTP/2时发生问题? - Lucidchart


HTTP 2是HTTP的一次重大飞跃。它通过对报头使用二进制压缩格式来提高带宽效率,通过在同一TCP连接上复用请求来减少延迟,并允许客户端指定请求的优先级。在许多情况下,迁移到HTTP / 2是正确的做法,但对于某些应用程序,HTTP / 2可能会导致严重的问题。
去年,在Lucidchart,我们在部分服务的负载均衡器上启用了HTTP / 2。此后不久,我们注意到HTTP / 2负载均衡器背后的服务器比其他服务器具有更高的CPU负载和更慢的响应时间。起初,原因尚不清楚,因为服务器流量看似正常,问题似乎与任何代码更改无关。仔细观察后,我们意识到请求的平均数量与通常相同,但实际请求流量变得更加集中:我们发现了大量请求的短暂爆发,而不是稳定的请求流。虽然我们根据以前的流量模式过度配置了容量,但仅仅处理这些新的请求峰值还是不够,因此对请求的响应被延迟并超时。
这里发生了什么呢?好吧,大多数浏览器限制到指定源的并发连接数(方案,主机和端口的组合),并且必须在单个连接上串行处理HTTP / 1.1连接。这意味着HTTP / 1.1浏览器有效地限制了对该源的并发请求数,这意味着我们的用户浏览器会限制对我们服务器的请求并保持流量顺畅。
还记得我说HTTP / 2如何添加多路复用?好吧,使用HTTP / 2,浏览器现在可以通过单个连接同时发送所有HTTP请求。从Web客户端的角度来看,这很棒。从理论上讲,客户端应该更快地获得所需的所有资源,因为在发出其他请求之前,它不再需要等待来自服务器的响应。但是,在实践中,多路复用大大增加了我们服务器的压力。
首先,因为他们大批量地而不是更小,更分散批次的接受请求;其次,因为使用HTTP / 2,请求全部一起发送 - 而不是像HTTP / 1.1那样交错发送 - 因此它们的开始时间更接近,这意味着它们都可能超时。

如何解决它
幸运的是,可以在不增加计算能力的情况下解决此问题。实际上,有一些潜在的解决方案,尽管它们比在负载均衡器中启用HTTP / 2需要更多的努力。

1. 负载平衡器上的节流阀
也许最明显的解决方案是让负载均衡器对应用程序服务器进行节流请求,因此从应用程序服务器的角度来看,流量模式与使用HTTP / 1.1时的流量模式类似。所需的难度取决于您的基础设施。
即使使用像HAProxy和Nginx这样的负载平衡器,获得正确的节流也会非常棘手。如果负载均衡器不支持限制,您仍然可以在负载均衡器和应用程序服务器之间放置反向代理,并在那里进行限制。

2.重新构建应用程序以更好地处理尖锋请求
另一个(也许更好)选项是更改应用程序,以便它可以处理来自接受HTTP / 2流量的负载均衡器的流量。根据应用程序的不同,这可能涉及向应用程序引入或调整排队机制,以便它可以接受连接,但一次只处理有限数量的连接。当我们切换到HTTP / 2时,我们实际上已经有了一个排队机制,但由于之前的一些代码决策,我们没有正确地限制并发请求处理。如果您执行队列请求,则应该注意不要在客户端等待响应超时后处理请求 - 不需要浪费不必要的资源。
在打开HTTP / 2之前,请确保您的应用程序可以处理两者的差异:HTTP / 2具有与HTTP / 1.1不同的流量模式。
您的应用程序可能是专门为HTTP / 1.1模式设计的,无论是否有意。HTTP / 2有很多好处,但是如果你不小心的话,它也有一些差别可以咬你。

后记
需要注意的另一个“问题”是支持HTTP / 2的软件尚未完全成熟。虽然它一直在变得越来越好,但HTTP / 2的软件还没有足够的时间来变得像现有的HTTP / 1.1软件一样成熟和稳固。
特别是,HTTP优先级的服务器支持充其量只是参差不齐。许多CDN和负载均衡器根本不支持它,或者有错误的实现,即使它们这样做,缓冲也会限制其有效性
此外,多个应用程序仅通过HTTPS支持HTTP / 2。从安全角度来看,这很棒。但是,它使得在不同组件之间不需要或不需要TLS的安全网络内的开发和调试变得复杂。这意味着您需要为localhost管理CA和证书以进行本地开发,记录会话机密以便使用Wireshark或类似工具检查HTTP / 2请求,并且可能需要额外的计算资源进行加密。