有了HTTP/2,Websocket还有市场吗?

原文地址:Will WebSocket survive HTTP/2?  (如有错误,欢迎大家批评指正,谢谢)。

互联网所依赖的协议正——HTTP,正处于一个重大的转变之中。这个转变带来了大量的疑问和关切,关于HTTP/2,正面负面的评价都有。尽管HTTP/2带来了很多新的能力,但是它并不能完全取代现有的推送技术和流技术。

关于HTTP/2,第一个需要注意的点是,它并非HTTP的完全替代品。请求方法、状态码和多数的头和现在保持一致。HTTP/2旨在提高数据在网络上的传输效率。

先看一下它同HTTP/1.x的关键不同之处,以及其解决的相关问题:

  • HTTP/2是二进制协议,HTTP 1.x是文本协议。二进制协议的解析效率更高,因为只有一种编码方法,而HTTP 1.x定义了4种不同的消息解析方式。二进制协议在网络上也有更高的空间效率。与此同时,因为二进制并非人类可读的格式,所以人类直接处理会更有难度。这就是权衡。
  • HTTP/2采用多路复用来解决一个称之为线头阻塞(HOL Blocking)的限制。这个问题可能发生于HTTP 1.1,发生在当多个请求到达同一个TCP连接(也称为HTTP流水线)时。由于整个的连接是有序且阻塞(FIFO)的,一个慢请求可能会占据这个连接,从而拖慢后续的所有请求。多路复用通过允许在一个连接上同时传递多个请求和响应解决了这个问题。
  • HTTP/2使用头压缩技术来降低负载。大小为1KB的头并非罕见,这主要是因为我们为了流畅的用户体验不得不接受的cookie。仅仅是为了交换头,这种1KB传输就可能经过几次网络往返,再者由于HTTP 1.x是无状态的,所以每次都要重新发送这些头。TCP的慢启动会加重这个问题,TCP会在第一次网络往返时限制发送包(packet)的数量。直到TCP有效地完成对网络的探测,找出可用容量并适当地调整其拥塞窗口之后,这个影响才结束。在这种场景下,对头的压缩会明显减少所需的网络往返的数量。
  • HTTP/2服务器推送让服务器能够主动推送响应到客户端缓存中。在典型的HTTP 1.x工作流中,浏览器请求一个页面,服务器在响应中返回一个HTML,然后就是等待浏览器解析响应并发送额外请求来获取额外的内嵌资源(JavaScript、CSS等)。服务器推送使服务器能够试探性地向客户端发送资源。此时,浏览器不必解析HTML页面并找到需要加载的其它资源;而是服务器能够立即开始发送它们。

现在,如果我们将HTTP/2同Websocket对比一下,我们能看到一些类似的地方:

HTTP/2

Websocket

压缩(HPACK)

二进制

二进制或者文本

多路复用

优先级

压缩

方向

客户端/服务器+服务器推送

双向

全双工

有了这些改进和类似的能力,很自然地就会问:HTTP/2是Websocket或者SSE这类推送技术的替代品吗?

答案显然是否定的,理由很简单:正如我们上面所看到的,HTTP/2引入了服务器推送,让服务器能够主动地推送资源到客户端缓存。然而它并没有允许推送数据到客户端应用本身。服务器的推送只是由浏览器来处理,并不会让应用代码介入,这也就意味着应用程序无法使用API来获取这些事件的通知。

这里就来到了“服务器发送事件”(Server-Sent Events SSE)的舞台了。SSE是一种让服务器能够在客户端服务器建立连接之后异步推送数据给客户端的机制。这样服务器就可以在数据“块”准备好之后再发送数据。这可以被看成是一种单向的发布订阅模型。多数的现代浏览器也实现了W3C HTML5标准中一个叫做EventSource的标准JavaScript客户端API。那些不支持EventSource API的浏览器,也可以方便地通过填充的方式来获得相应的支持。

由于SSE是基于HTTP的,其天然适配于HTTP/2,这样SSE就可以集两者之长:HTTP/2可以基于多路复用流形成一个高效传输层,同时SSE给应用提供了API使之能够进行推送。

为了完全理解流和多路复用是什么,我们先来看一下IETF的定义:“流”就是一个独立的、在客户端服务器之间的HTTP/2连接上双向的帧序列。其重要的一个特征就是单个的HTTP/2连接可以包含多个并发开启的流,其中每个端点都交错着来自多个流的帧。

为了避免上述的定义将你整得云里雾里(我就是如此:-)),下面的这一张来自于Nginx博客的图片清晰地解释了其意义:

有了HTTP/2,Websocket还有市场吗?_第1张图片

如果想要实验一下HTTP/2多路复用是如何在实际中工作的,可以尝试一下这个demo,不要忘了使用你喜欢的浏览器打开开发者窗口。如果你不确定你的浏览器是否支持HTTP/2,可以快速浏览一下这里。

使用HTTP/1,应该会有如下的输出:

有了HTTP/2,Websocket还有市场吗?_第2张图片

浏览器会并行打开多个HTTP/1.x连接来加速页面加载。不同的浏览器对于针对统一域名并发打开的连接数量有不同的限制,基本上都会支持6个左右不同的连接。为了克服这个限制,类似于域名分片的技术就被用来将资源分布在多个域名上。这些技术(我们可以将其认为是非法入侵)包括连接JavaScript和CSS文件、图像和资源内联,在HTTP/2世界中反而适得其反。这可能是迁移到HTTP/2的时候收到的最主要的影响了:消除多年以来所做的优化。

当使用HTTP/2的时候,会看到浏览器使用单个多路复用的连接,带来更快的加载时间。

有了HTTP/2,Websocket还有市场吗?_第3张图片

现在我们已经了解了什么是多路复用,我们必须始终记得SSE是基于HTTP的。这意味着使用HTTP/2的时候,不仅仅可以在一个TCP连接上交错多个SSE流,同时也支持多个SSE流(服务器到客户端)服务多个客户端请求(客户端到服务器)。有了HTTP/2和SSE,我们现在就可以使用一个纯HTTP双向连接,加之使用简单的API使应用代码注册多个服务器推送。双向能力的缺失一直是SSE对比Websocket时最主要的短板。有了HTTP/2就弥补了这个短板。这就为跳过Websocket并坚持使用基于HTTP的机制提供了可能。

回答开始提出的问题:有了HTTP/2,Websocket还有市场吗?

答案是肯定的,主要是因为它已经被大量应用,同时在某些特定应用场景下,其底层设计致力于双向能力,拥有较少的负载的优势就会体现出来。假设需要在双端之间交互大吞吐量的消息,其中上下流动的消息量大致差不多(比如,需要保持所有玩家同步的大型多人在线游戏),这种场景下Websocket可能会是更好的选择。

如果考虑像是展示实时市场新闻、市场数据、聊天应用等场景的时候,依赖HTTP/2+SSE会提供高效的双向通信通道并保有留在HTTP世界的大量优势:

  • Websocket由于是从将一个HTTP连接升级到一个完全不同的,与HTTP协议没有关系的协议,所以当考虑将其与现有Web基础设施做兼容的时候就比较难受了。
  • 扩展性和安全:Web基础设施组件(防火墙,入侵检测、负载均衡)已经基于HTTP建立、维护和设置了,这是一个大型/关键应用在弹性、安全性和可扩展性等方面更加友好的环境。

总结一下

  • HTTP/2并非HTTP的完整替代。
  • 类似于域名分片、资源内联和图片拼接等入侵入式技术在HTTP/2世界中正好适得其反。
  • HTTP/2不是类似于Websocket或者SSE这样的推送技术的替代品。
  • HTTP/2推送服务器只能被浏览器来处理,而不是应用。
  • 将HTTP/2和SSE结合起来提供高效的基于HTTP的双向通信。

Websocket技术可能会继续使用,但是SSE和其EventSource API同HTTP/2的能力相结合可以在多数场景下达到同样的效果,但是会更简单。

你可能感兴趣的:(互联网,Web,http,websocket,网络)