HTTP / 1.x与HTTP / 2
首先,让我们看看有哪些高层差异:
- HTTP / 2是二进制的,而不是文本的
与HTTP / 1.x等文本协议相比,二进制协议更有效地解析,在信道上更紧凑,最重要的是,与HTTP / 1.x等文本协议相比,它们更不容易出错,因为它们通常具有一些像空白处理,大写,行结尾,空白等等的“帮助” 。
例如,HTTP / 1.1定义了四种不同的解析消息的方法; 在HTTP / 2中,只有一个代码路径。
- HTTP / 2是完全多路复用的,而不是有序和阻塞的
HTTP / 1.x有一个称为“行头阻塞”(head-of-line blocking)的问题,实际上一次只有一个请求在连接上活动。
HTTP / 1.1试图通过流水线修复此问题,但它没有完全解决问题(大的或慢的响应仍然可以阻止在后面的请求)。此外,发现流水线很难部署,因为许多中介和服务器不能正确处理它。
这迫使客户端使用一些启发式方法(通常是猜测)来确定哪些请求放在哪个连接到源的时候; 由于页面加载10次(或更多)可用连接的数量是常见的,这会严重影响性能,通常会形成阻塞请求的“瀑布”。
多路复用通过允许多个请求和响应消息同时在传输中来解决这些问题; 甚至可以将一条消息的一部分与另一条消息混合在一起。
反过来,这允许客户端每个源只使用一个连接来加载页面。
- HTTP / 2可以使用一个连接进行并行
使用HTTP / 1,浏览器可以在每个源的4到8个连接之间打开。由于许多站点使用多个源,这可能意味着单个页面加载打开超过30个连接。
一个应用程序打开这么多连接同时打破了许多基于TCP的假设; 由于每个连接都会在响应中传输大量数据,因此存在中间网络中的缓冲区溢出,导致拥塞事件和重新传输的真实风险。
您可以在此处查看HTTP / 2如何工作的演示:
此外,使用如此多的连接不公平地垄断网络资源,将其从其他更好的应用程序(例如,VoIP)“窃取”。
- HTTP / 2使用Header压缩来减少开销
如果你假设一个页面有大约80个资源(在今天的Web上是保守的),并且每个请求有1400个字节的标题(并不罕见),它至少需要7-8个来回为了让他们发送至客户端,这不是在计算响应时间。
这是因为TCP的慢启动机制,它根据已确认的数据包数量在新连接上发出新的数据包 - 有效地限制了前几次往返可以发送的数据包数量。
相比之下,即使是Header上的稍微压缩也允许这些请求在一次往返中发送完,甚至可能是只一个数据包。
这种开销很大,特别是当您考虑对移动客户端的影响时,即使在良好的条件下,移动客户端通常也会看到几百毫秒的往返延迟。
- HTTP / 2允许服务器主动将响应“推送”到客户端缓存中
当浏览器请求页面时,服务器在响应中发送HTML,然后需要等待浏览器解析HTML并发出对所有嵌入资源的请求,然后才能开始发送JavaScript,图像和CSS。
服务器推送可能允许服务器通过将其认为客户端需要的响应“推送”到其缓存中来避免这种延迟的往返。
但是,推动响应并不“神奇” - 如果使用不当,可能会损害性能。目前,许多人仍将继续与Webhooks合作。
它如何影响在HTTP / 1.1上构建的现有REST API?
HTTP的主要语义已保留在HTTP / 2中。这意味着,它仍然有HTTP方法,如GET,POST,HTTP headers和URIs识别资源。
HTTP / 2相对于HTTP / 1.1的变化是HTTP语义(例如“我想POST主机domain.com上的资源/ foo”)通过网络传输的方式。这意味着在HTTP / 1.1上构建的REST API将继续像以前一样透明地工作,而不会对应用程序进行任何更改。
运行应用程序的Web容器将代表应用程序将新的线路格式转换为通常的HTTP语义,并且应用程序只会看到更高级别的HTTP语义,无论它是通过HTTP / 1.1还是HTTP /2传输。
由于HTTP / 2 传输格式更有效(特别是由于多路复用和压缩),HTTP / 2之上的REST API也将从中受益。
HTTP / 2,HTTP / 2 Push中存在的另一个主要改进是针对相关资源的有效下载,并且在大多数REST API用例中可能没用,也许只有像服务这样的对象存储可以从中受益(如Amazon S3) )。
HTTP / 2的典型要求是通过TLS部署。这需要部署者从HTTP移动到HTTPS。这意味着多一些开销
HTTP / 2的好处
HTTP / 2带来的关键改进包括多路复用流,报头压缩,服务器推送和二进制协议,而不是文本协议。这些和其他积极的变化允许实现良好的网页加载结果,包括那些附加了大量附加文件的结果(例如样式,脚本,图像,字体等)。
HTTP / 2是HTTP协议的新版本,它还为服务器到服务器通信提供了许多新功能:
- 使用推送请求的双向通信
HTTP / 2的“服务器推送”允许服务器主动将内容发送到客户端的缓存以供将来使用。
例如,这有助于避免在获取HTML和链接的样式表和CSS之间的往返; 服务器可以立即开始发送这些内容,而无需等待客户端请求它们。
它对于有些人需要的主动更新或使客户端缓存无效也很有用
当然,在某些情况下,客户端不希望某些东西被推送到它 - 通常是因为它已经有一个副本,或者知道它不会使用它。在这些情况下,它只能用RST_STREAM说“不”。
- 在单个TCP连接中进行多路复用
HTTP / 2使用多路复用来允许许多消息同时在一个连接上交错在一起,这样一个大的响应(或一个需要很长时间让服务器思考的响应)不会阻止其他消息。
此外,它增加了标头压缩,因此正常的请求和响应标头不会占据您的带宽 - 即使您请求的内容非常小。这在移动设备上是一个巨大的胜利,毕竟通过几次往返,获取大量请求标头可以轻松地耗费大量资源的页面加载时间。
- 长时间连接
HTTP / 2旨在使用更少的连接,因此服务器和网络将享受更少的负载。当网络变得拥挤时,这一点尤其重要,因为HTTP / 1使用多个连接进行并行化会增加问题。
例如,如果您的手机打开六个到每个服务器的TCP连接以下载页面的资源(记住这些天大多数页面使用多个服务器),它很容易使移动网络的缓冲区过载,导致它们丢弃数据包,触发重传和使问题更严重。
HTTP / 2允许每个主机使用单个连接,并鼓励站点在可能的情况下在一个主机上合并其内容。
- 有状态的联系
如果您的HTTP / 1客户端发送请求然后发现它不需要响应,如果它想要节省带宽,则需要关闭连接,没有安全的方法来恢复它。
HTTP / 2添加RST_STREAM帧以允许客户端改变主意; 如果浏览器导航离开页面,或者用户取消下载,则可以避免在不浪费所有带宽的情况下打开新连接。
同样,这是关于改善感知性能和网络友好性; 通过允许客户端在这种常见场景中保持连接活动,可以避免额外的往返和资源消耗。
与往常一样,并非一切都与利益有关,但存在一些可疑的缺点:
- 使用二进制而不是文本
这也是一个好的,不太好的功能。
关于HTTP / 1的一个好处是能够打开telnet,输入请求(如果服务器没有超时!)然后查看响应。这在HTTP / 2中不实用,因为它是二进制协议。为什么?
考虑如何将short int 30000(0x7530)存储为文本和二进制文件:
如您所见,我们使用2个字节而不是使用5个字节。它减小了50%以上的尺寸。
虽然二进制协议具有较低的解析开销,以及稍微更轻的网络占用空间,但这一重大变化的真正原因是二进制协议更简单,因此更不容易出错。
那是因为文本协议必须涵盖诸如如何分隔字符串(计算?double-newline?),如何处理空格,额外字符等问题。这导致了很多实现的复杂性; 在HTTP / 1中,至少有三种方法可以告知消息何时结束,以及一组复杂的规则来确定使用哪种方法。
HTTP / 1的文本性质也是许多安全问题的根源; 因为不同的实现做出关于如何解析消息的不同决定,所以恶意方可以摆弄他们的方式(例如,通过响应分裂攻击)。
远离文本的另一个原因是,任何看起来像HTTP / 1的东西都将被处理为HTTP / 1,当你添加多路复用等基本功能时(将内容与错误信息相关联会产生灾难性后果),你需要做一个干净的休息。
当然,对于那些只想调试协议的穷人来说,所有这些都是一个小小的慰借。这意味着我们需要新工具和大量工具来解决这个缺点; 首先,Wireshark已经有了一个插件。
- 更多加密
HTTP / 2不要求您使用TLS(SSL的标准形式,即Web的加密层),但其更高的性能使得使用加密变得更容易,因为它减少了对网站看起来速度的影响。这意味着您可能需要购买SSL证书,续订等等。当您使用REST API处理许多微服务时,这不是一笔不小的钱。
事实上,许多人认为在“开放”互联网上部署新协议的唯一安全方法是使用加密; Firefox和Chrome表示他们只支持使用TLS的HTTP / 2。
他们有两个原因。一个是在Internet上部署新版本的HTTP很难,因为代理和防火墙等许多“中间盒”都假设HTTP / 1不会发生变化,并且如果他们尝试使用它们就会引入互操作性甚至安全问题解释HTTP / 2连接。
另一个是Web是一个越来越危险的地方,使用更多加密是缓解大量威胁的一种方法。通过使用HTTP / 2作为站点使用TLS的胡萝卜,他们希望Web的整体安全性能够得到改善。
总结
如果大多数可能基于REST的微服务都在进行服务器到服务器的通信,那么现有REST API的真正好处就在于此。在今天的微服务架构中,当许多微服务以多种方式在它们之间进行交谈但仍使用REST时,HTTP / 2可以提高工作流的速度。
HTTP / 2不定义JavaScript API,也不会帮助您更轻松地构建REST API。目前,在Web浏览器中运行的JavaScript客户端只能有限地使用新功能。但是,对于服务器到服务器的通信,HTTP / 2提供了许多方法来超越现有的REST API。
此外,HTTP / 2的网络友好性的缺点是它使TCP拥塞控制更加明显; 现在浏览器每个主机只使用一个连接,初始窗口和数据包丢失更加明显。
就像HTTP经历了一段时间的审查,实验和演变一样,很明显社区的注意力转向TCP及其对性能的影响; 关于在IETF中调整甚至替换TCP的问题,我们已经进行了早期讨论。