The Wayback Machine - https://web.archive.org/web/20210126045230/https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/290
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 140 题:为什么 HTTP1.1 不能实现多路复用 #290

Open
yygmind opened this issue Oct 14, 2019 · 15 comments
Open

第 140 题:为什么 HTTP1.1 不能实现多路复用 #290

yygmind opened this issue Oct 14, 2019 · 15 comments
Labels

Comments

@yygmind
Copy link
Contributor

@yygmind yygmind commented Oct 14, 2019

No description provided.

@yygmind yygmind added the 腾讯 label Oct 14, 2019
@yygmind yygmind changed the title 第 140 题:为什么 Http1.1 不能实现多路复用 第 140 题:为什么 HTTP1.1 不能实现多路复用 Oct 14, 2019
@Dreams-d
Copy link

@Dreams-d Dreams-d commented Oct 14, 2019

可能是因为http1.1是纯文本吧,不是二进制帧的原因?

@qitian7
Copy link

@qitian7 qitian7 commented Oct 14, 2019

HTTP1.x是序列和阻塞机制

HTTP 2.0 是多工复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"。

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

  • 旧的http1.1是会等 A请求完全处理完后在 处理B请求,会阻塞

  • 另:http1.1已经实现了管道机制:即 在同一个TCP连接里面,客户端可以同时发送多个请求。http 1.0并做不到,所以效率很低

@heart-er
Copy link

@heart-er heart-er commented Oct 14, 2019

1.首先http 1.1是一个慢启动的过程,在起初建立连接的时候会慢慢的寻找一个稳定的速度,然后选择这个稳定速度的大小来进行发送数据
2.正是因为慢启动的原因,每个资源在传送的时候都会寻找一个合适的发送大小,因此会造成每个资源间的竞争,因此,在同时开启了多个tcp连接的情况下,这些资源都会去竞争带宽
3.http 1.1有一个队头阻塞的问题,当一个请求因为某些原因而在队头阻塞的时候,从而导致后面的请求被延迟,效率非常低

@Mrlie
Copy link

@Mrlie Mrlie commented Oct 14, 2019

1.首先http 1.1是一个慢启动的过程,在起初建立连接的时候会慢慢的寻找一个稳定的速度,然后选择这个稳定速度的大小来进行发送数据
2.正是因为慢启动的原因,每个资源在传送的时候都会寻找一个合适的发送大小,因此会造成每个资源间的竞争,因此,在同时开启了多个tcp连接的情况下,这些资源都会去竞争带宽
3.http 1.1有一个队头阻塞的问题,当一个请求因为某些原因而在队头阻塞的时候,从而导致后面的请求被延迟,效率非常低

感觉跟1,2没关系,现在TCP RENO版本的拥塞控制设计都是先进入慢启动阶段,无论http1.1 还是http2.0

@mayloveless
Copy link

@mayloveless mayloveless commented Oct 14, 2019

没有序列号标签,交错发送无法排序

@teachat8
Copy link

@teachat8 teachat8 commented Oct 14, 2019

HTTP/1.x 有个问题叫队头阻塞,即一个连接同时只能有效地承载一个请求。

HTTP/1.1 试过用流水线来解决这个问题,但是效果并不理想(数据量较大或者速度较慢的响应,仍然会阻碍排在后面的响应)。此外,由于网络中介和服务器都不能很好的支持流水线技术,导致部署起来困难重重。

客户端被迫使用一些启发式的算法(基本靠猜)来决定哪些连接来承载哪些请求;由于通常一个页面加载资源的连接需求,往往超过了可用连接资源的 10 倍,这对性能产生极大的负面影响,后果经常是引起了风暴式的阻塞。

而多路复用则能很好的解决这些问题,因为它能同时处理多个消息的请求和响应;甚至可以在传输过程中将一个消息跟另外一个糅合在一起。

所以客户端只需要一个连接就能加载一个完整的页面。

@mengsixing
Copy link

@mengsixing mengsixing commented Oct 17, 2019

HTTP/1.1 不是二进制传输,而是通过文本进行传输。由于没有流的概念,在使用并行传输(多路复用)传递数据时,接收端在接收到响应后,并不能区分多个响应分别对应的请求,所以无法将多个响应的结果重新进行组装,也就实现不了多路复用。

@webgzh907247189
Copy link

@webgzh907247189 webgzh907247189 commented Oct 22, 2019

HTTP/1.x 有个问题叫队头阻塞,即一个连接同时只能有效地承载一个请求。

HTTP/1.1 试过用流水线来解决这个问题,但是效果并不理想(数据量较大或者速度较慢的响应,仍然会阻碍排在后面的响应)。此外,由于网络中介和服务器都不能很好的支持流水线技术,导致部署起来困难重重。

客户端被迫使用一些启发式的算法(基本靠猜)来决定哪些连接来承载哪些请求;由于通常一个页面加载资源的连接需求,往往超过了可用连接资源的 10 倍,这对性能产生极大的负面影响,后果经常是引起了风暴式的阻塞。

而多路复用则能很好的解决这些问题,因为它能同时处理多个消息的请求和响应;甚至可以在传输过程中将一个消息跟另外一个糅合在一起。

所以客户端只需要一个连接就能加载一个完整的页面。

HTTP/1.x 有个问题叫队头阻塞,即一个连接同时只能有效地承载一个请求。

HTTP/1.1 试过用流水线来解决这个问题,但是效果并不理想(数据量较大或者速度较慢的响应,仍然会阻碍排在后面的响应)。此外,由于网络中介和服务器都不能很好的支持流水线技术,导致部署起来困难重重。

客户端被迫使用一些启发式的算法(基本靠猜)来决定哪些连接来承载哪些请求;由于通常一个页面加载资源的连接需求,往往超过了可用连接资源的 10 倍,这对性能产生极大的负面影响,后果经常是引起了风暴式的阻塞。

而多路复用则能很好的解决这些问题,因为它能同时处理多个消息的请求和响应;甚至可以在传输过程中将一个消息跟另外一个糅合在一起。

所以客户端只需要一个连接就能加载一个完整的页面。

http2.0 也存在队头阻塞问题,如果造成队头阻塞,问题可能比http1.1还严重,因为只有一个tcp连接,后续的传输都要等前面,http1.1 多个tcp连接,阻塞一个,其他的还可以正常跑

@Arsenalfanscz
Copy link

@Arsenalfanscz Arsenalfanscz commented Nov 1, 2019

HTTP/1.x 有个问题叫队头阻塞,即一个连接同时只能有效地承载一个请求。
HTTP/1.1 试过用流水线来解决这个问题,但是效果并不理想(数据量较大或者速度较慢的响应,仍然会阻碍排在后面的响应)。此外,由于网络中介和服务器都不能很好的支持流水线技术,导致部署起来困难重重。
客户端被迫使用一些启发式的算法(基本靠猜)来决定哪些连接来承载哪些请求;由于通常一个页面加载资源的连接需求,往往超过了可用连接资源的 10 倍,这对性能产生极大的负面影响,后果经常是引起了风暴式的阻塞。
而多路复用则能很好的解决这些问题,因为它能同时处理多个消息的请求和响应;甚至可以在传输过程中将一个消息跟另外一个糅合在一起。
所以客户端只需要一个连接就能加载一个完整的页面。

HTTP/1.x 有个问题叫队头阻塞,即一个连接同时只能有效地承载一个请求。
HTTP/1.1 试过用流水线来解决这个问题,但是效果并不理想(数据量较大或者速度较慢的响应,仍然会阻碍排在后面的响应)。此外,由于网络中介和服务器都不能很好的支持流水线技术,导致部署起来困难重重。
客户端被迫使用一些启发式的算法(基本靠猜)来决定哪些连接来承载哪些请求;由于通常一个页面加载资源的连接需求,往往超过了可用连接资源的 10 倍,这对性能产生极大的负面影响,后果经常是引起了风暴式的阻塞。
而多路复用则能很好的解决这些问题,因为它能同时处理多个消息的请求和响应;甚至可以在传输过程中将一个消息跟另外一个糅合在一起。
所以客户端只需要一个连接就能加载一个完整的页面。

http2.0 也存在队头阻塞问题,如果造成队头阻塞,问题可能比http1.1还严重,因为只有一个tcp连接,后续的传输都要等前面,http1.1 多个tcp连接,阻塞一个,其他的还可以正常跑

对的,这也是为什么http3.0出来的主要原因之一
在HTTP/2中,多个请求是跑在一个TCP管道中的。但当出现了丢包时,HTTP/2 的表现反倒不如 HTTP/1 了。因为TCP为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP/2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP连接中的所有请求(如下图)。而对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
https://mp.weixin.qq.com/s/sakIv-NidqkO1tviBHxtWQ

@irina9215
Copy link

@irina9215 irina9215 commented Nov 18, 2019

多路复用归功于, HTTP/2 中的 帧(frame)和流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。就是在一个 TCP 连接中可以存在多条流。

而Http 1.x 并没有这个标识,每次请求都会建立一次HTTP连接,3次握手4次挥手。

@yygmind yygmind added the 网络 label Dec 16, 2019
@bbrucechen
Copy link

@bbrucechen bbrucechen commented Jan 3, 2020

HTTP/1.1 不是二进制传输,而是通过文本进行传输。由于没有流的概念,在使用并行传输(多路复用)传递数据时,接收端在接收到响应后,并不能区分多个响应分别对应的请求,所以无法将多个响应的结果重新进行组装,也就实现不了多路复用。

终于有个回答到点子上的了

@blade254353074
Copy link

@blade254353074 blade254353074 commented Mar 8, 2020

多路复用归功于, HTTP/2 中的 帧(frame)和流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。就是在一个 TCP 连接中可以存在多条流。

而Http 1.x 并没有这个标识,每次请求都会建立一次HTTP连接,3次握手4次挥手。

HTTP 1.1 默认有 Keep-Alive,建立连接的一定时间内,不会每次请求都建立新的 TCP 连接。

@PeterRock
Copy link

@PeterRock PeterRock commented Apr 13, 2020

@JaykeyGuo
Copy link

@JaykeyGuo JaykeyGuo commented Oct 27, 2020

多路复用:实际上是指一个TCP/IP链接提供给多个HTTP链接使用,在1.1的标准中,HTTP还是以文本的方式传输,有响应和应答的方式,这样确保能到达另一端,但这也带了的问题就是需要等待响应。一个socket链接只能给一个HTTP使用,不能把一个完整的文本拆成流来处理,比较优化的方式也是只是根据Content-length来分割,最后让浏览器来拼装。

核心是HTTP1.1是基于文本的传输方式,还是一个一个文件。

而HTTP2.0则是使用流的方式来传输,可以把一个文件分包,根据Id来拼装,做到一个socket链接中传输多个文件的需求。

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