2、HTTP1/HTTP2/HTTP3

前言:HTTP请求和响应的步骤

2.1、HTPP1

在了解HTTP1之前先来了解HTTP0.9,HTTP0.9功能很简单,就是用来实现在网络之间传递HTML超文本内容,采用的是请求响应模式,客户端发送请求,服务端返回数据。

HTTP0.9请求完整过程

  • 获取IP地址,端口号和服务器建立TCP连接,TCP连接的过程就是TCP协议的三次握手
  • 建立好连接后会发送一个GET请求行的信息,例如GET /index.html用来获取index.html
  • 服务器接收到请求后会读取对应的HTML文件,并将数据以ASCLL字符流的形式返回给客户端
  • HTML文档输出完成,断开连接

总的来说,当时需求简单就只是用来传输体积小的HTML文件,所以总结下HTTP0.9的特点

  • 只有一行请求行,没有请求头和请求体
  • 只有一行响应头,因为服务器并并不需要返回太多信息,只需要返回数据就行
  • 返回的文件都是以ASCLL字符流的形式进行传输,因为都是HTML格式的文件,所以用ASCLL字符流的形式进行传输最合适。

HTTP1:

由于万维网的高速发展,浏览器展示的不仅仅时HTML文件,还包括CSS、js、图片、视频、音频等不同类型的文件,所以HTTP0.9不再满足我们的需求,HTTP1也就随之诞生,为了让客户端和服务端有更深入的交流,HTTP1引入了响应头和请求头,它是以Key-Value形式保存的。

HTTP1需要解决的几个问题:

  • 处理不同类型的文件
  • 为了减轻传输的性能,服务器都会将数据进行压缩后再传输,所以浏览器需要知道解压的方法
  • 服务器需要对不同的地区提供不同的语言版本,所以浏览器需要告诉服务器需要什么样的语言
  • 不同类型的文件编码格式可能不一样,所以浏览器需要知道文件的编码格式

基于以上问题,HTTP/1.0 的方案是通过请求头和响应头来进行协商,在发起请求时候会通过 HTTP 请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码 ,服务器接收到浏览器发送的请求信息之后,会根据请求头的信息准备响应数据, 不过有时候会有一些意外情况发生,比如浏览器请求的压缩类型是 gzip,但是服务器不支持 gzip,只支持 br 压缩,那么它会通过响应头中的 content-encoding 字段告诉浏览器最终的压缩类型,也就是说最终浏览器需要根据响应头的信息来处理数据。

HTTP1新增的几个典型的特性:

  • 状态码,用来告诉浏览器请求处理的情况,状态码是通过响行的形式通知浏览器。
  • Cache机制,用来缓存已经下载过的数据。
  • 务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。

HTTP1升级版HTTP1.1:

HTTP1出现的问题:

  • 每次进行HTTP通信都需要经历TCP连接、数据传输、断开连接三个阶段,一旦请求的数据较多,每次请求都要经历这个过程,就会增加大量的无谓开销。
  • 后一次请求需要的等待前一次请求完成之后才能请求,如果某个请求因为一些原因发生阻塞,就会影响后面的请求,这就是“队头阻塞”问题。
  • 在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。
  • 在HTTP1中每个域名绑定了唯一的IP地址,因此服务器只能支持一个域名。

HTTP1.1解决机制:

  • 增加持久化连接,它的特点是在一个TCP连接上可以传输多个HTTP请求,只要浏览器或者服务器没有明确断开连接,那么该TCP连接会一直保持。
  • 不成熟的HTTP管线化,原理是将多个HTTP请求整批提交给服务器,虽然可以整批发送请求,但是服务器任然需要根据请求顺序来回复浏览器,由于各种原因最终也就放弃了管线化技术。
  • HTTP1.1利用chunk transfer机制解决数据的动态生成,服务器会将数据分割成若干任意大小的数据块,每个数据块会带上这个数据块的长度,最后使用一个零长度的数据块作为数据发送完成的标志。
  • 随着虚拟主机的发展,一台物理主机可以绑定多个虚拟主机,每个虚拟主机都有自己的单独域名,这些单独的域名都共用同一个IP地址。所依HTTP1.1在请求头中增加了HOST字段表示当前域名地址,这样服务器就可以根据不同的HOST做不同的处理。

HTTP2

同样在说HTTP2前先了解下HTTP1.1存在的问题,HTTP1.1在HTTP1的基础上采取了很多优化加载速度的策略,也取得了一定的效果,但是HTTP1.1对宽带的利用率不够理想,带宽指每秒能发送或者将接受的的字节数,之所以说HTTP1.1对宽带的利用率不够理想,是因为HTTP1.1很难将带宽用满,下面分析原因。

  • TCP启动慢

    一但TCP建立连接后,就进入发送数据的状态,刚开始TCP会采用一个非常慢的速度去传输数据,然后逐渐加快速度,直到发送数据的速度达到一个理想的状态,这个过程被称为慢启动。慢启动时TCP减少网络拥塞的一种策略,我们无法改变,那么为什么说慢启动会带来性能问题呢?是因为页面常用的关键资源本来就不大,如HTML文件、js文件、css文件,这些文件在TCP建立好之后就要开始发送,但是由于TCP采用的是慢启动的模式,所以耗费的时间摇臂正常的时间多很多。

  • TCP之间的竞争

    在系统建立多条TCP连接的时候,如果带宽充足,那么每条TCP的发送或者接受速度就会慢慢增加,当宽带不足时,这些TCP连接的发送或者接受速度就会慢慢减慢,这样就会出现一个问题,因为有的TCP连接下载的是一些关键资源,有的是一些普通资源,但是TCP之间又不能够去协商优先加载哪些资源,这就会影响到关键资源的下载。

  • 队头阻塞

    在一个TCP连接中,一个时刻只能处理一个请求,在前面的请求没有结束之前,其他的请求都处于等待状态,这会造成CPU和带宽的浪费,这是一个很严重的问题,同时阻塞请求的原因有很多,并且都是一些不确定的因素。

HTTP2的解决方案

  • 采用一个TCP长连接来传输数据

    为了规避TCP的慢启动和TCP连接之间竞争问题,HTTP2就采用一个TCP长连接来传输数据,这样整个页面就只需要慢启动一次同时也不存在TCP竞争的问题。

  • 多路复用机制

    处理方式:实现了资源并行请求,也就是任何时候都可以将请求发送给服务器,那个不需要等待其他请求完成,然后服务器也可以随时返回处理好的请求资源给浏览器。

    实现原理

从图中可以知道,HTTP2新添加了一个二进制分帧层,下面分析整个过程。

  • 浏览器准备好请求数据,包括请求行、请求头等信息,如果是POST请求,还要包括请求体
  • 请求进入二进制分帧层会被转换为一个个带有请求ID编号的帧,通过协议栈将这些帧发送给服务器。
  • 服务器接受到所有帧后,会将相同的ID合并为一条完整的请求信息,然后服务器处理该请求,并将响应头、响应行和响应体发送至二进制分帧层。
  • 同样二进制分帧层会将这些响应数据转换成一个个带有请求ID编号的帧,经过协议栈发送给浏览器。
  • 浏览器接收到响应帧后,会根据ID编号帧提交给对应的请求

HTTP2的其他特性

  • 可以设置请求优先级

在发送请求时,有些重要的请求可能晚于那些不怎么重要的请求,如果这些重要的请求按照请求的顺序来执行,那么这些重要的数据就会被推迟很久才能送达到浏览器,这样对用户的体验是不有好的,所以HTTP2提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求后会根据请求的优先级来处理请求。

  • 服务器推送

除了设置请求的优先级外,HTTP/2 还可以直接将数据提前推送到浏览器。你可以想象这样一个场景,当用户请求一个 HTML 页面之后,服务器知道该 HTML 页面会引用几个重要的 JavaScript 文件和 CSS 文件,那么在接收到 HTML 请求之后,附带将要使用的 CSS 文件和 JavaScript 文件一并发送给浏览器,这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用。

  • 头部压缩

无论是HTTP1还是HTTP2都有请求头和响应头,HTTP2对请求头和响应头进行了压缩,比如一个页面需要加载100个左右的资源,如果将100个请求头的数据压缩为原来的20%,那么传输效率肯定会得到很大的提高。

HTTP3

老规矩看看HTTP2哪那么些问题:

  • TCP的队头阻塞

    在TCP中数据是通过虚拟管道进行传输的,计算机的一端将要传输的数据按照顺序放入管道,最终数据会以相同的顺序出现在管道的另一头。对于一个完整的数据,它会被拆分成一个个按照顺序排列的数据包,这些数据包网络传输到接收端,接收端再按照顺序将这些数据包组合成原始的数据。不过在传输的过程中,如果某个数据包因为网络故障或者其他原因而丢失,那么整个TCP的连接就会处于暂停状态,需要等待丢失的数据包重新传输过来。 我们就把在 TCP 传输过程中,由于单个数据包的丢失而造成的阻塞称为 TCP 上的队头阻塞。

快速重传、选择性重传和快速恢复:

  • 快速恢复

在TCP传输的过程中如果发生丢包,即接收端发现数据不是按顺序到达的,接收端的处理就是重复发送之前的ACK,比如在传输的过程中第 5 个包丢了,即使第 6、7 个包到达的接收端,接收端也一律返回第 4 个包的 ACK。当发送端收到 3 个重复的 ACK 时,意识到丢包了,于是马上进行重传,不用等到一个 RTO 的时间到了才重传。这就是快速重传,它解决的是是否需要重传的问题

  • 选择性恢复

那你可能会问了,既然要重传,那么只重传第 5 个包还是第5、6、7 个包都重传呢?

当然第 6、7 个都已经到达了,就不用重传了,干脆记录一下哪些包到了,哪些没到,针对性地重传。

在收到发送端的报文后,接收端回复一个 ACK 报文,那么在这个报文首部的可选项中,就可以加上SACK这个属性,通过left edgeright edge告知发送端已经收到了哪些区间的数据报。因此,即使第 5 个包丢包了,当收到第 6、7 个包之后,接收端依然会告诉发送端,这两个包到了。剩下第 5 个包没到,就重传这个包。这个过程也叫做选择性重传(SACK,Selective Acknowledgment),它解决的是如何重传的问题

  • 快速恢复

发送端收到三次重复 ACK 之后,发现丢包,觉得现在的网络已经有些拥塞了,自己会进入快速恢复阶段。在这个阶段,发送端会做出一些改变。

  • 拥塞阈值降低为 cwnd 的一半
  • cwnd 的大小变为拥塞阈值
  • cwnd 线性增加
  • TCP建立连接的延时

    我们把从浏览器发送一个数据包到服务器,服务器再返回数据包到浏览器的过程叫做一次RTT,RTT是反映网络性能的一个重要指标。下面来算一算TCP建立连接需要多少个RTT。

    • 建立TCP连接的时候需要三次握手来确定连接成功,这个过程需要1.5个RTT
    • 如果是HTTPS的话,还需要使用TLS协议进行安全传输,而TLS也需要一次握手,这个过程的RTT根据TLS的版本有关,大致需要1-2RTT

    总之这个过程我们需要3-4个RTT,如果浏览器和服务器的物理距离较近,那用户当然可以接收,但是一旦比较远,那用户就能明显感觉到变慢了。

  • TCP协议僵化

    既然TCP协议存在这么多问题,为什么不直接通过改进TCP协议解决这些问题?如果条件允许的话那当然可以,但是有两个非常困难的问题,首先是中间设备的僵化,什么是中间设备,其实从字面意思就可以知道,就是让互联网正常运行的各种依赖设备,比如路由器、防火墙、交换机等各种设备,他们通常依赖于很少会升级的软件,,而这些软件又大量的使用了TCP特性,这些功能被设置之后就很少更新了。如果我们单纯的在客户端升级TCP,但是这些中间设备不认识这些包的内容,最后这些资源也会被丢弃掉。除此之外还有一个困难就是操作系统,因为TCP是通过操作系统的内核来实现的,而应用程序只能使用不能修改,通常操作系统的更新滞后于软件更新,所以想要自由的更新内核中TCP协议是非常困难的。

QUIC协议

为了解决HTTP2中出现的一系列问题,HTTP3采用了一个折中的方法,HTTP3使用了UDP协议,因为我们如果想绕过TCP协议和UDP协议这同样会面临中间设备的僵化问题,所以HTT3才会采用UDP协议,但是不是单纯的使用UDP协议,而是在这个协议基础上实现了类似TCP的多路数据流、传输可靠性等功能,下面说说QUIC协议的功能。

  • 实现了类似TCP的流量控制和传输可靠性功能。

    虽然UDP不提供保证数据传输可靠的功能,但QUIC在UDP的基础上增加了一层来保证数据可靠性传输,他提供数据包重传,拥塞控制以及其他TCP中存在的特性。

  • 集成了TLS加密功能

  • 实现HTTP2中多路复用

    和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

  • 实现快速握手功能

    因为QUIC是基于UDP来实现的,所以QUIC可以实现用0-1个RTT来实现建立连接。

了解HTT1/HTT2/HTT3 ?相关推荐

  1. JDK8升级JDK9 HTT2 TLS问题解决之路(艰辛)

    背景描述 s公告服务是雪球行情的公告抓取服务,主要负责从相关网站抓取A股.港股.美股公告,调用接口发贴.数据抓取是在该业务场景是行情数据的入口,影响以后的的处理逻辑.因此,通过代理池+proxy的方式 ...

  2. android手机apk动态替换桌面的logo和laber

    具体操作如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android= ...

  3. centos下安装apache + subversion(转)

    目录: 一.安装apr跟apr-util 二.安装apache服务器 三. 安装subversion 四. 配置subversion 五. 配置apache的httpd.conf 六. 验证安装 七. ...

  4. Grpc+Grpc Gateway实践二 有些复杂的Hello World

    Hello World 在上一节中我们已经完成了对环境的基本配置 这节将开始编写一个复杂的Hello World,涉及到许多的知识,建议大家认真思考其中的概念 需求 由于本实践偏向Grpc+Grpc ...

  5. SVN在centos5.4的安装步骤:

    (我的环境是centos5.4  apache版本:httpd-2.2.15  subversion 版本:subversion-1.5.6) 目录: 一.安装apr跟apr-util 二.安装apa ...

  6. eShopOnContainers 知多少[11]:服务间通信之gRPC

    1. 引言 最近翻看最新3.0 eShopOncontainers源码,发现其在架构选型中补充了 gRPC 进行服务间通信.那就索性也写一篇,作为系列的补充. 2. gRPC 老规矩,先来理一下gRP ...

  7. 并发测试工具_性能测试工具基本工作原理及基本操作流程

    性能测试的基本概念 性能测试:是指在特定情况下测试系统如何执行的.资源的使用.可扩展性和可靠性也是性能测试的范畴.性能测试是性能工程的一个子集,主要发现软件架构以及设计导致的性能问题. 性能测试的目标 ...

  8. scal的函数定义(day01)

    函数定义.函数作为参数.函数调用: //定义函数/*def 是函数,sum是函数名,a是变量,b是变量,返回值Int*/def sun(a:Int,b:Int):Int={return a+b}//函 ...

  9. HTTP2.0多路复用

    上篇文章介绍了http1.1相对于http2的一些不足,本篇文章来聊一聊http2的一些优点,但是http2的优点比较多,并且需要结合源码展示,所以关于htt2的一些特点,我打算拆分成多篇文章,本篇文 ...

最新文章

  1. grub2引导linux内核,一种基于grub2的linux系统启动bootloader的制作方法与流程
  2. 命令行修改weblogic用户名和密码
  3. 地表地形对地下温度及地表热流的影响
  4. caffe 在 windows 使用
  5. [css] CSS3新增伪类有哪些并简要描述
  6. 实现线程安全的单例模式的四种方式
  7. c#连mysql的latin1编码乱码问题
  8. python turtle画中国象棋_Python turtle绘画象棋棋盘
  9. OC:跟随小码哥一起学习KVC
  10. Qt开发经验总结之武林秘籍(转)
  11. 全民农场服务器维修,微信全民农场新手常见问题集锦
  12. 【踩坑日记 · 嵌入式 Linux】在香橙派 Zero 2 上编译安装 CH340 驱动(OrangePi Zero 2)
  13. php中die是什么意思,PHP中die()和exit()有什么区别?
  14. 9、RH850 SPI(CSIH) 通讯功能和配置
  15. 关于python安装问题 0x80072f7d的解决方法
  16. python 发送邮件
  17. 航海世纪服务器维护中,航海世纪: 下周五航海世纪 迎来主流服务器黑珍珠号
  18. Java基础 DAY15
  19. 计算机题库一级第四,计算机一级题题库,第四章Excel
  20. STM32H750VB程序无法下载的问题

热门文章

  1. 編程之美2.9:神奇的菲波那契數列
  2. parseInt()和parseFloat()的解析原理
  3. vue 八大生命周期
  4. 检索式对话系统在美团客服场景的探索与实践
  5. 吾爱这个PDF处理小工具,我私藏了一年才偷偷分享!
  6. Java实验报告(6)
  7. CentOS 7配置httpd服务器
  8. CSS - 精灵图和字体图标
  9. Mixamo上传自定义模型动画导入Unreal4
  10. 如何使用VNC进行远程桌面控制