xiaohanliang
Network
Network
  • hi
  • LOWER
    • 0. arp决定下一跳
    • 1. dns决定终点
    • 2. [WIP]dns是不是真的有这些层级
  • MIDDLE
    • 0. 如何理解tcp握手的设计
    • 1. 诡异的tcp拆包现象
    • 2. tcp是一种高效的协议吗
    • 3. 为什么说没有人可以裸用tcp
    • 4. 尝试理解tcp的设计
    • 5. 连接建立@tcp调优
    • 6. 连接断开@tcp调优
    • 7. [WIP]拥塞控制@tcp调优
    • 8. 不需要这些花里胡哨的东西
    • 9. 怎么又是socket又是tcp
  • UPPER
    • 0. 为什么大家都用http
    • 1. [WIP]为什么http也keep-alive
    • 2. 如何保证pipeline的顺序到达
    • 3. 如何保证http的安全性
    • 4. 只不过https基于tls连接
    • 5. 怎么理解get/post
    • 6. http2为什么更快
    • 7. [WIP]内置加速的http3
    • 8. 怎样制造出实时效果-ws
    • 9. kcp是如何榨干你的带宽的
  • DEVICES
    • [302] 跳转到Linux网络设备
  • KUBERNETES NETWORK
    • [302] 跳转到容器网络
Powered by GitBook
On this page
  • background
  • introduction
  • 为什么折腾呢?
  • http2的其他特性
  • 本质还是HTTP1的模式

Was this helpful?

  1. UPPER

6. http2为什么更快

Previous5. 怎么理解get/postNext7. [WIP]内置加速的http3

Last updated 4 years ago

Was this helpful?

background

1.1相比于1来说:

  • [顺序化] 的请求使用长链接来避免产生频繁的握手/拥塞控制适应期

  • [非顺序化的请求] 的请求跟1一样还是并发的启动

另外你可能知道我们在1.1里面有一个pipeline模式, 但实际如果启用遇到比如我们之前曾经说的head-of-line blocking等问题, 因此不太常使用它. 除此之外二者在通行模式上差别不是特别大.

如下图所示, 假设我们想要并发的请求三个文件, 下面二者分别是在常规模式/piplining模式下的通讯过程, 其中管道模式的问题之前我们已经介绍过了

introduction

我们还是以上面的请求为例, 我们现在需要发两个请求, 在上面的图中, 最直观的区别就是现在出现了两个新概念, [stream] 以及 [frame]

  • 流就是一个请求, 或者一个响应, 比如你发给服务器的GET请求, 如果你现在有两个HTTP请求想要发送给服务器, 你就会生成两个流

  • 帧就是这个请求的一部分, 我们把我们的几个请求打碎成帧, 然后这些帧作为TCP管道里的最小单元流淌在管道里, 如上图所示, 来自不同流的帧一起发过去, 一个请求可以这样被打碎:

    • HTTP请求的HEADER作为第一帧

    • HTTP请求的BODY作为第二帧

上面那是一个HTTP2抓包示范, 1号流代表了服务器的响应, 我们请求css文件, 服务器做出的HTTP响应被当成了一个流, 1号流被分成了两个帧, 第一个帧是Header帧, 里面有HTTP响应的Header, 第二个帧是Data帧, 象征了css文件本体, 并且135号流的帧是交替混在一起发过来的

为什么折腾呢?

你已经知道了HTTP请求还是那些请求, 只是被打碎成帧发过去了, 现在请问这是为什么. 想要了解为什么要设计出 "流" 的概念:

  1. 你需要了解为什么Pipelining为什么不被大规模使用 →

  2. 因为如果第一个延迟了, 第二个第三个都响应不了 →

  3. 因为客户端不知道哪个resp对应哪个req, 他只知道顺序 →

  4. 因为HTTP请求没有序号的概念

好, 答案已经出来了, 因为没有序号, 所以没法把响应与请求对应上, 这才导致了2号3号的延迟, 很巧, 这个我们有, 因此在HTTP2里我们就能先回复2号跟3号, 这种谁先好谁就先回复的行为, 我们在HTTP2里叫它 Multiplexing

http2的其他特性

  • server push: 这点有点像websocket, 服务器可以主动给客户端发送消息, 一般出现在这种场景下, 比如客户端索要 index.html , 我除了发 index.html以外, 还可以主动给你发 main.js/css 等, 你拿到了以后先缓存着, 等等你就用上了

  • header compress: 这种做法的背景是我们都知道HTTP能帮你通过比如gzip压缩, 但是本质上还是只压缩了Body, 而现实中大量请求都没什么body, 只有Header, 因为HTTP是没有状态的因此Header需要反复发送, 且不能压缩. 在H2里面常用的Header名被一个index(数字)所指代, 第一次发送的时候需要带上值, 后面发送的时候只用这个数字就可以了

本质还是HTTP1的模式

HTTP2虽然玩了很多花样, 但是无论如何离不开HTTP里面通过Header做注解, Body传数据的这种玩法, 也就是说对于服务端而言, 协议本身没有变过, 处理方式也没变过, 唯一变化的还是传输过程, 传输方式没有变过.