HTTP协议之:HTTP/1.1和HTTP/2_http1.1和http2-程序员宅基地

技术标签: restful  java  CS揭秘  http  程序那些事  

简介

HTTP的全称是Hypertext Transfer Protocol,是在1989年World Wide Web发展起来之后出现的标准协议,用来在WWW上传输数据。HTTP/1.1是1997年在原始的HTTP协议基础上进行的补充和优化。

到了2015年,为了适应快速发送的web应用和现代浏览器的需求,发展出了新的HTTP/2协议,主要在手机浏览器、延时处理、图像处理和视频处理方面进行了优化。

基本上所有的现代浏览器都支持HTTP/2协议了,但是还有很多应用程序使用的是老的HTTP/1.1协议,本文将会介绍HTTP/1.1和HTTP/2的不同之处。

HTTP/1.1

HTTP 1.0 是由Timothy Berners-Lee在1989年作为World Wide Web的标准协议发布的。通常使用HTTP方法如:GET或者POST,以TEXT文本的形式在客户端和服务器端进行消息传输。

我们可以使用post man很方便的进行HTTP请求,如下所示:

GET /index.html HTTP/1.1
Host: www.flydean.com

客户端通过GET请求,请求服务器端的/index.html页面,使用的协议是HTTP/1.1,服务器端收到该请求之后,会将相应以文本的形式返回给客户端。

HTTP协议是对底层的TCP/IP协议的封装,因为我们不需要交接具体的报文拆分和封装的底层细节,只需要关注于具体的业务逻辑即可,非常的方便。

HTTP/2

HTTP/2是从SPDY协议发展出来的,它的发起者是Google,最初是为了在web交互中引入压缩、多路复用等新的技术,最终在2015年被作为HTTP/2协议的一部分。

之前我们讲到HTTP/1.1是以文本的形式进行传输的,这样的缺点就是数据占用的空间比较大,相较于HTTP/1.1来说HTTP/2使用的是二进制进行传输的,使用二进制对消息进行封装,同时保留了HTTP的语义,比如方法,头等。

这种二进制的封装对应用层是无感知的,对于应用来说,还是按照常用的方法来创建HTTP请求,将其封装成二进制的工作是由HTTP/2来完成的。

传输模式对比

在HTTP1.0中,每当客户端向服务器端请求页面的时候,往往返回的不是一个完整的页面,而是这个页面还需要的额外的资源链接信息,因为完整的页面需要所有的资源都下载完毕之后才能展示,所以在HTTP1.0中,客户端需要中断当前的连接,然后重新建立新的连接去请求资源。这会额外耗费多余的资源和时间。

在HTTP1.1中,引入了持久连接和管道的概念,这样不用每次请求都去重新开启和新建连接,HTTP默认底层的TCP连接是open的,除非手动告诉它要去关闭。在这种情况下,客户端可以使用同一个连接去和server进行交互,从而极大的提升HTTP的效率。

虽然在HTTP1.1中可以使用同一个连接进行数据传输了,但是对于这个连接来说,其中的请求是一一响应的,他们是有顺序的。如果最前面的请求被阻塞了,后面的请求也得不到响应。这种情况被称为head-of-line (HOL) blocking。

为了解决这个问题,可以在client和server端建立多个连接,这样就可以利用多个connection并行进行数据的传输,从而提升传输效率。

但是这样的缺点就是新建连接会消耗太多的资源,并且客户端和服务器端的连接个数也是有限的。

所以HTTP/2出现了。

在 HTTP/2 中,数据以二进制的的格式进行传输,其本身是将原始请求的切分成为更小的信息包,从而大大增加了数据传输的灵活性。

HTTP1.1需要建立多个TCP连接从而解决并行传输的问题,但是在HTTP/2 中只需要建立一个连接就够了。在这个连接中可以传输多个数据流,每个数据流中又包含多个message包,每个message又被切分为多个数据frame。

这些数据frame可以在传输期间交换位置,然后在接收的另一端重新组装。 交错的请求和响应可以并行运行,从而不会阻塞它们背后的消息,这个过程被称为多路复用。 多路复用的机制使得一个消息不用等待另外一个消息发送完成,从而解决了HTTP/1.1 中的队头阻塞问题。 这也意味着服务器和客户端可以发送并发请求和响应,从而实现更好的控制和更有效的连接管理。

多路复用虽然构建了多个消息流,但是只占用了一个TCP连接,从而减少整个网络的内存和处理占用空间,得到更好的网络和带宽利用率,从而降低整体运营成本。

单个TCP连接还提高了HTTPS协议的性能,因为客户端和服务器可以为多个请求/响应重用相同的安全会话。 在HTTPS中,在TLS或SSL握手期间,双方在整个会话期间使用单个密钥。 如果连接中断从新开始新的会话,则需要新生成的密钥进行进一步通信。 因此,维护单个连接可以大大减少HTTPS所需的资源。

请注意,尽管HTTP/2规范并未强制要求使用TLS,但许多主要浏览器仅支持带有HTTPS的HTTP/2。

流优先级

虽然HTTP/2解决了多个数据frame通常传输的问题,但是对于同一个资源来说,必须要等到的所有的数据frame都接受完毕之后才能展示,如果我们想优先展示某个资源该怎么做呢?

HTTP/2提供了流优先级的解决方案。

在客户端向服务器端发送消息的时候,消息会以流的形式在连接中传输,这些流可以分配1到256之间的权重来确定其请求的响应的优先级。 数字越大表示优先级越高。 除此之外,客户端还通过指定它所依赖的流的ID来说明每个流对另一个流的依赖关系。 如果省略父标识符,则认为该流依赖于根流。

服务器会使用流中的ID构建一个依赖树,从而确定其相应的顺序。

应用程序的开发人员可以根据需要自行设置请求的优先级,比如在网页中提供低分辨率的缩略图的同时提供低优先级的高分辨率的图像。通过为资源分配不同的优先级,开发人员能够更好地控制网页渲染。

缓冲区溢出处理

不管是哪种协议,客户端和服务器端在接收数据的时候都有一个缓冲区来临时存储暂时处理不了的数据,但是缓冲区的大小是有限制的,所以有可能会出现缓冲区溢出的情况,比如客户端向服务器端上传一个大的图片,就有可能导致服务器端的缓冲区溢出,从而导致一些额外的数据包丢失。

为了避免缓冲区溢出,各个HTTP协议都提供了一定的解决办法。

在HTTP1.1中,流量的控制依赖的是底层TCP协议,在客户端和服务器端建立连接的时候,会使用系统默认的设置来建立缓冲区。在数据进行通信的时候,会告诉对方它的接收窗口的大小,这个接收窗口就是缓冲区中剩余的可用空间。如果接收窗口大小为零,则说明接收方缓冲区已满,则发送方将不再发送数据,直到客户端清除其内部缓冲区,然后请求恢复数据传输。

因为HTTP1.1使用多个TCP连接,多以可以对每一个TCP连接进行单独的流量控制。但是HTTP2使用的是多路复用的模式,所以它的流量控制方式和HTTP1.1是不同的。

HTTP2是通过客户端和服务器端的应用中进行缓冲区大小消息的传输,是通过在应用层层面控制数据流,所以各个应用端可以自行控制流量的大小,从而实现更高的连接效率。

HTTP/2提供了更详细的控制级别,从而开启了更大优化的可能性。

预测资源请求

在一个典型的web应用中,当客户端发动一个GET请求到服务器端的时候,通常客户端会发现所以需要的不止一个资源,还可能包含了CSS或者其他JS等资源。但是客户端只有在首次获取到服务器端的响应时候才能真正确认到底需要哪些资源。然后需要额外请求这些资源以完成整个请求。但是这些额外的请求最终会增加连接加载时间。

那么有没有可能服务器在客户端请求之前将资源发送给客户端呢?我们看下HTTP1.1和HTTP2是怎么做的。

在HTTP1.1中,主要使用的资源内联的方式,比如将客户端所需要的CSS或者JS资源包含在服务器最初发送的HTML文档中,也就是做内联操作,从而减少客户端必须发送的请求总数。

但是这样的解决方案也有问题。因为一般来说资源内联一般是针对较小的资源来说的,如果资源文件太大的话,就会大大的增加HTML文件的大小,从而抵消减少连接提升的速度优势。

另外如果资源被放在HTML中,那么客户端就没有可能对这些资源进行缓存,从而影响整体的效率。

在HTTP/2中使用的是服务器推送。因为HTTP/2在同一个连接中可以发送多个stream,所以服务器可以将资源与请求的HTML页面一起发送到客户端,在客户端请求之前提供资源。 这个过程被称为服务器推送。

这样就可以在不用新开连接的同时,实现HTML文档和资源的分离和同时推送。

但是在HTTP/2中,服务器推送是由应用程序来控制的,所以控制起来会比较复杂。我们会在后续的文章中详细讲解HTTP/2的服务器推送。

压缩

通常为了减少数据在网络中的传输,我们需要对数据进行压缩,接下来我们看一下在HTTP1.1和HTTP2中都是怎么做的。

在HTTP1.1中,通常使用gzip对HTTP中的消息进行压缩,主要是针对CSS文件和javascript文件,但是HTTP的消息头还是由纯文本来发送的,另外由于cookie的使用,导致HTTP消息头的大小会越来越大,从而对程序的性能造成一定的影响。

在HTTP/2中,使用的算法是HPACK算法,同时可以对HTTP头和数据分别进行压缩,从而大大减少其大小。

总结

HTTP/2在HTTP1.1的基础上进行了更加细粒度的优化控制,并提供了包括多路复用、流优先级、流量控制、服务器推送和压缩等高级特性。非常强大。希望大家能够喜欢。

本文已收录于 http://www.flydean.com/02-http1-1-vs-http2/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/superfjj/article/details/119923133

智能推荐

JNI编程示例-程序员宅基地

文章浏览阅读681次。源代码地址:链接:百度网盘 请输入提取码提取码:gtlz一、Demo介绍为了更深入的理解Jni编程知识,我们通过一个简单demo把相关知识用实际代码串起来,会有更清晰的认识。在这个demo中,涉及数组处理、字符串处理、类成员变量访问修改等内容,基本涵盖了常见的用法。 相关介绍 涉及文件 (java代码/xml布局文件) demo界面示例 主界面 点击button进入对应示例 s

Struts2之图书管理系统_用spring整合采用struts2开发的登录程序,实现同样的“图书管理系统”登录功能-程序员宅基地

文章浏览阅读666次。趁着周末,梳理一下前几周学的struts2,回顾起struts2,它和springmvc同是action层的解决方案,讲图书系统的同时,先让我们了解一下三层架构,以SSH框架为例。参考来源:http://blog.csdn.net/inter_peng/article/details/410217271.Action/Service/DAO简介:Action是管理业务(Service)..._用spring整合采用struts2开发的登录程序,实现同样的“图书管理系统”登录功能

yolov8的predict使用方法,更改predict.py的输出结果,输出label的真实坐标,保存图片和txt文档,图片中没有异物生成空的txt文档_yolov8 predict-程序员宅基地

文章浏览阅读1.4w次,点赞23次,收藏135次。更改predict.py的输出结果,输出label的真实坐标,保存图片和txt文档,图片中没有异物生成空的txt文档_yolov8 predict

JAVA线程之Thread类详解-程序员宅基地

文章浏览阅读9.7w次,点赞42次,收藏195次。ss_thread

lynis-程序员宅基地

文章浏览阅读89次。 lynis 是个不错的安全审计工具。 常见用法:lynis -c 逐项手动检查,并在最后给出建议lynis -Q 显式自动扫描,并在最后给出建议lynis -q 静默自动扫描,只给出警告 顺便说下另一个问题,在centos 5下安装lynis出错: ERROR with rpm_check_debug vs depsolve:rpmlib(Fil..._languard network scanner 2.0

## 实现MQTT数据在MySQL上的数据持久化实验_用c# 实现emqx 数据持续化到mysql-程序员宅基地

文章浏览阅读663次。一.硬件连接二.软件部分1.云服务器2.安装宝塔面板在腾讯云上安装宝塔面板:安装SSH 连接工具,安装步骤https://www.bt.cn/bbs/thread-1971-1-1.html,挂载磁盘后(查看),根据系统执行框内命令开始安装(这里我选用的是Ubuntu系统)在云服务中打开端口(入站规则和出站规则都要添加)找到腾讯云公网IP地址,在浏览器中输入该IP地址+端口(这里我采用的是8888端口)3.安装EMQX Cloud在云服务器上安装EMQX Cloud,下载链接:htt_用c# 实现emqx 数据持续化到mysql

随便推点

小球碰撞边框并停下的代码-程序员宅基地

文章浏览阅读245次。package test;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Graphics;import java.awt.Image;import java.awt..._c语言小球碰撞后停止

Python使用递归法和函数式编程计算整数各位之和-程序员宅基地

文章浏览阅读1.5k次。问题描述:给定一个正整数,计算其各位数字之和。参考代码:程序运行无任何输出,表示两个函数结果一致。----------相关阅读----------1900页Python系列PPT分享一:基..._python输入一串正整数折半递归求和

信号采集系统的硬件连接笔记_地开信号采集-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏6次。在使用差分或者RSE方式时,由于信号负端不与AIGND连接,放大器的输入偏置电流有可能会使信号电压偏离测量设备的量程范围,所以需要在信号两端与AIGND之间分别加一个偏置电阻,从系统平衡角度而言,建议取等值的两电阻,阻值范围一般在10kΩ和100kΩ之间。无参考地单端(NRSE)连接方式的测量系统是对RSE连接方式的一种变形,各路信号共享一个基准点,而仪用放大器负极正是与这个公共基准点相连的,但并不与系统地相连,所以测得信号是以该基准点作为参考点的电压信号。这样可以实现信号地与系统地之间的隔离。_地开信号采集

sublime text python c++_sublime python中如何用 c++-程序员宅基地

文章浏览阅读810次。1.python/c++指定pathctrl+b编译ctrl+shift+b编译运行2.c++实现控制台输出使用批处理文件。本解决方法以C语言程序为例,编译器是gcc,我下载了MINGW直接解压到C盘根目录下,并设置了相应的PATH。其它编程语言可以按照这个思路适当修改批处理文件。新建两个批处理文件,一个名为runp.bat,内容如下:@ec_sublime python中如何用 c++

python基础——matplotlib——scatter和plot方法中的maker参数(点的样式)_python scatter marker-程序员宅基地

文章浏览阅读2w次,点赞15次,收藏66次。一、scatterscatter方法主要用来做散点图展示,而plot方法主要用来做折线图展示,也可以用于散点图的展示。两个方法的参数基本是通用的。以scatter方法为例,常用参数包括:plt.scatter( ['x', 'y', 's=None', 'c=None', 'marker=None', 'cmap=None', 'norm=None', 'vmin=None', 'vmax=None', 'alpha=None', 'linewidths=None', 'verts=&._python scatter marker

【MQTT协议详解】MQTT协议-程序员宅基地

文章浏览阅读3.2w次,点赞39次,收藏399次。MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于 **发布/订阅** 范式的消息协议。它工作在TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。 *简而言之,MQTT其实就是一个用于TCP通信的消息协议而已。既然消息协议,"消息" 自然是表示MQTT其实本质就是消息,消息在某种理解上,可以理解报文,报文包,数据等等;既然是协议,自然表示它有着自己的规则,什么叫规则?就是规定这个消息该以怎样的**........_mqtt协议