作为开发人员,我们的主要目标一直是为产品的用户提供更快、更无缝的体验。这种持续改进生产力和用户体验的渴望使我们几乎不断地升级技术。我们迁移到更新版本的语言、Web框架、消息队列和文本处理器以及操作系统。但是,由Web应用程序普遍使用的基本协议HTTP协议已经超过十年没有进行升级了。
HTTP/1.1非常好,但随着Web应用程序规模和复杂性的增长,它的年龄开始显现。这是升级到HTTP/2的好时机。
HTTP/1.2 发生了什么?
新HTTP的目标非常高,为了实现这些指标,必须根本性地改变数据在网络上的传输方式。HTTP/2引入了一个新的二进制框架层,打破了与HTTP/1.x客户端和服务器的向后兼容性。因此,版本跳跃到2.0。
这个新的二进制框架层是什么?
这是一个简单的设计选择。HTTP/1.x传统上使用换行符分隔的文本来传输数据。与二进制相比,它速度更慢、体积更大、更容易出错。因此,HTTP/2在传输层中进行了二进制格式的切换。
这指的是如何在套接字和我们从应用程序公开的HTTP API之间编码数据的设计更改,而不是API本身。将运行应用程序的Web容器将负责根据其支持的HTTP版本进行编码,而不需要对API层进行任何更改。
语义仍然是相同的。你仍然可以像在HTTP 1.x中一样使用传统的GET、PUT、POST、DELETE。
我的主要收益是什么?
不必深入探讨二进制流如何工作,让我们用这句话来总结一下,然后进入它如何帮助我们的内容:
HTTP/2将HTTP协议通信分解为交换二进制编码的帧,这些帧然后映射到属于特定流的消息中,所有这些消息都在单个TCP连接中进行多路复用。
现在,进入收益:
1.二进制处理:二进制内容更快、更轻、更紧凑。HTTP/1.x有四种不同的消息解析选项,而HTTP/2只有一种。此外,二进制内容更支持处理大写、空格、空行和其他一些难以用文本表示的概念。
2.多路复用:HTTP/1.x基本上是建立在一次只能传送一个响应的原则之上的。这导致了响应排队和阻塞,减慢了TCP连接。这意味着直到现在,客户端必须猜测需要获取哪些响应才能快速处理事情。
HTTP/2取消了这个概念,新的二进制流使得完全请求和响应多路复用成为可能。因此,客户端只需要一个连接来自一个源,就能够并行传递多个请求和响应,而不会相互阻塞。这反过来通过消除不必要的延迟和提高可用网络容量的利用率来提供更低的页面加载时间。
3.头部压缩:HTTP/2使用HPACK压缩技术来压缩跨请求和响应的头部数据。
HPACK使用Huffman编码压缩头部,同时客户端和服务器维护先前看到的头部列表以便更快的编码和解释。在今天的平均请求中,我们可以看到跨越几千字节的头部,而头部压缩极大地提高了效率。
4.服务器推送:在HTTP/1.x中,服务器只能在请求被请求时与客户端通信,并且只能通过响应来通信。然而,在HTTP/2中,服务器可以向单个请求发送多个响应。因此,在响应之外,服务器还可以向客户端推送其他有用的信息。例如,在加载网页时,服务器可以立即开始发送javascript文件和样式表,而不必等待客户端请求它们。它也可以用于活动更新客户端的缓存,以实现更快的渲染。
我如何转移到HTTP/2?
由于如此多的好处,组织一直在稳步向HTTP/2迁移,它的使用率不断增加。目前,32.4%的网站使用HTTP/2。该行业有信心这个数字只会上升。那么,你如何跳上这辆列车呢?
如前所述,为了过渡到HTTP/2,不需要对应用程序层进行任何真正的更改,因为更改是在编码和信息传输机制中进行的。
如果你使用cURL,请检查当前版本: curl --version
你将会收到一个协议列表:dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
。如果你在其中没有看到http2,你可以简单地更新cURL版本。Mac 用户可以直接执行以下命令:
brew reinstall curl --with-openssl --with-nghttp2
对于其他操作系统,你可以参考 这篇有用的文章。
现在,如何更新你的 Web 服务器和容器呢?每个服务器和容器都需要进行稍微不同但非常简单和最小的更改,而且不会影响现有代码的兼容性。
我主要使用 Spring Boot 来开发应用程序。它有一个嵌入式的 Tomcat 服务器,从版本 1.4.x
开始就支持 HTTP/2,它使用的是 Tomcat 版本 8.5.x
。我们只需要将 HTTP/2 升级协议添加到 Tomcat 的连接器中即可。我们可以通过自定义嵌入式 Tomcat 容器来完成这项工作:
@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
return (container) -> {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
((TomcatEmbeddedServletContainerFactory) container)
.addConnectorCustomizers((connector) -> {
connector.addUpgradeProtocol(new Http2Protocol());
});
}
};
}
如此简单!
现在所有流行的 Web 框架都支持 HTTP/2,迁移非常简单,而且可以为用户提供更好的体验。我希望这篇文章能引导你向 HTTP/2 迁移的方向前进。
评论(0)