Skip to content

第 15 题:简单讲解一下 http2 的多路复用 #14

Open
@ZodiacSyndicate

Description

@ZodiacSyndicate

HTTP2采用二进制格式传输,取代了HTTP1.x的文本格式,二进制格式解析更高效。
多路复用代替了HTTP1.x的序列和阻塞机制,所有的相同域名请求都通过同一个TCP连接并发完成。在HTTP1.x中,并发多个请求需要多个TCP连接,浏览器为了控制资源会有6-8个TCP连接都限制。
HTTP2中

  • 同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。
  • 单个连接上可以并行交错的请求和响应,之间互不干扰

Activity

sisterAn

sisterAn commented on Feb 20, 2019

@sisterAn
Collaborator

在 HTTP/1 中,每次请求都会建立一次HTTP连接,也就是我们常说的3次握手4次挥手,这个过程在一次请求过程中占用了相当长的时间,即使开启了 Keep-Alive ,解决了多次连接的问题,但是依然有两个效率上的问题:

  • 第一个:串行的文件传输。当请求a文件时,b文件只能等待,等待a连接到服务器、服务器处理文件、服务器返回文件,这三个步骤。我们假设这三步用时都是1秒,那么a文件用时为3秒,b文件传输完成用时为6秒,依此类推。(注:此项计算有一个前提条件,就是浏览器和服务器是单通道传输)
  • 第二个:连接数过多。我们假设Apache设置了最大并发数为300,因为浏览器限制,浏览器发起的最大请求数为6,也就是服务器能承载的最高并发为50,当第51个人访问时,就需要等待前面某个请求处理完成。

HTTP/2的多路复用就是为了解决上述的两个性能问题。
在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)和流(stream)。
帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。

azl397985856

azl397985856 commented on Mar 31, 2019

@azl397985856

简单来说, 就是在同一个TCP连接,同一时刻可以传输多个HTTP请求。

之前是同一个连接只能用一次, 如果开启了keep-alive,虽然可以用多次,但是同一时刻只能有一个HTTP请求

Hiker9527

Hiker9527 commented on Apr 2, 2019

@Hiker9527

http/1中的每个请求都会建立一个单独的连接,除了在每次建立连接过程中的三次握手之外,还存在TCP的慢启动导致的传输速度低。其实大部分的http请求传送的数据都很小,就导致每一次请求基本上都没有达到正常的传输速度。

在http1.1中默认开启keep-alive,解决了上面说到的问题,但是http的传输形式是一问一答的形式,一个请求对应一个响应(http2中已经不成立,一个请求可以有多个响应,server push),在keep-alive中,必须等下上一个请求接受才能发起下一个请求,所以会收到前面请求的阻塞。

使用pipe-line可以连续发送一组没有相互依赖的请求而不比等到上一个请求先结束,看似pipe-line是个好东西,但是到目前为止我还没见过这种类型的连接,也间接说明这东西比较鸡肋。pipe-line依然没有解决阻塞的问题,因为请求响应的顺序必须和请求发送的顺序一致,如果中间有某个响应花了很长的时间,后面的响应就算已经完成了也要排队等阻塞的请求返回,这就是线头阻塞。

http2的多路复用就很好的解决了上面所提出的问题。http2的传输是基于二进制帧的。每一个TCP连接中承载了多个双向流通的流,每一个流都有一个独一无二的标识和优先级,而流就是由二进制帧组成的。二进制帧的头部信息会标识自己属于哪一个流,所以这些帧是可以交错传输,然后在接收端通过帧头的信息组装成完整的数据。这样就解决了线头阻塞的问题,同时也提高了网络速度的利用率。

Lie8466

Lie8466 commented on Apr 10, 2019

@Lie8466

HTTP1.X的线头阻塞问题指的是统一域名下的请求会有阻塞问题吗?还是说页面的所有请求都必须按顺序相应

changed the title [-]第15题:简单讲解一下http2的多路复用[/-] [+]第 15 题:简单讲解一下http2的多路复用[/+] on Apr 26, 2019
changed the title [-]第 15 题:简单讲解一下http2的多路复用[/-] [+]第 15 题:简单讲解一下 http2 的多路复用[/+] on Apr 26, 2019
Hiker9527

Hiker9527 commented on Apr 26, 2019

@Hiker9527

HTTP1.X的线头阻塞问题指的是统一域名下的请求会有阻塞问题吗?还是说页面的所有请求都必须按顺序相应

正常情况下一个http请求就会建立一个TCP连接,在这种情况下就不存在线头阻塞。但是当多个请求复用一个TCP连接时才可能出现这个问题。不同域名的请求当然不能共用一个TCP连接,而且就算是同一个域名下的请求,也要看服务器支不支持pipeline。即使服务器支持pipeline,也要根据自己的实际使用场景来决定要不要以pipeline的形式发送请求。

aimeefe

aimeefe commented on Jul 20, 2019

@aimeefe

http/1.0:如需要发送多个请求必须创建多个 TCP 连接,并且浏览器对于单域名请求有数量限制(一般6个),其连接无法被复用

http/1.1:引入流水线(Pipelining)技术,但先天 FIFO(先进先出)机制导致当前请求的执行依赖于上一个请求执行的完成,容易引起报头阻塞,并没有从根本上解决问题

http/2:重新定义底层 http 语义映射,允许同一个连接上使用请求和响应双向数据流。同一域名只需占用一个 TCP 连接,通过数据流(Stream)以帧为基本协议单位,从根本上解决了问题,避免了因频繁创建连接产生的延迟,减少了内存消耗,提升了使用性能

资料:《koa 与 nodejs 开发实战》 http 篇

NuoHui

NuoHui commented on Jul 22, 2019

@NuoHui
yingye

yingye commented on Jul 25, 2019

@yingye

简单版回答:

HTTP/2 复用 TCP 连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应。

举例来说,在一个TCP连接里面,服务器同时收到了A请求和B请求,于是先回应A请求,结果发现处理过程非常耗时,于是就发送A请求已经处理好的部分, 接着回应B请求,完成后,再发送A请求剩下的部分。

历史原因解释:

1、HTTP/1.0 版本

该版本主要缺点是,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。为了解决这个问题,需要使用 Connection: keep-alive 这个字段。

2、HTTP/1.1 版本

该版本引入了持久连接(persistent connection),即 TCP 连接默认不关闭,可以被多个请求复用,不用声明 Connection: keep-alive。还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。

虽然1.1版允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。

weixiaoxu123

weixiaoxu123 commented on Aug 16, 2019

@weixiaoxu123

在http1.1 中 默认允许 connect: keep-alive 但是在一个TCP里面 数据通信时按次进行,也就是说第二次请求发送要在第一次响应后进行,若第一次响应慢,则要一直阻塞。这个问题就是对头阻塞。
在HTTP/2.0中,在一个TCP链接中,客户端和服务器可以同时发送多个请求和响应,则避免了对头阻塞, 实现了 双向 实时 多工。 在2.0中 采用了数据流,对同一个请求或响应的所有数据包做了一个独一无二的标识,所以可以不用等待发送。两端会根据标识组装数据流。

28 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @huanzhiyazi@DevinXian@Soyn@jiangjiu@yuexunshi

        Issue actions

          第 15 题:简单讲解一下 http2 的多路复用 · Issue #14 · Advanced-Frontend/Daily-Interview-Question