HTTP/2优势在哪

HTTP/2优势在哪

学习资源 小林coding 2022.4.4

HTTP/1.1性能问题

  • 消息大小变大
  • 资源变多
  • 内容形式多样
  • 实时性要求高

HTTP/1.1高延迟 -> 影响用户体验

  • 延迟难以下降
  • 并发数量有限 每个连接TCP TLS握手 TCP慢启动
  • 队头阻塞 同一连接只能在完成一个HTTP事务(请求和响应)后 才能处理下一个事务
  • HTTP头部巨大且重复 HTTP-> 无状态协议 每一个请求都需要携带HTTP头部 尤其是对于有cookie的头部
  • 不支持服务器推送信息 客户端需要获取通知时 只能通过定时器不断拉取消息 浪费带宽 资源

优化手段

  • 多个小图合并大图 用js切割 减少请求量 问题:小图更新重新请求大图
  • 图片二进制Base64编码 嵌入HTML/CSS文件 减少网络请求次数
  • 多个体积较小的使用webpack 打包成体积更大的JS文件
  • 统一资源分散到不同域名 提升并发上限 浏览器通常对于统一域名的HTTP连接最大是6

不能优化的地方

  • 请求响应模型
  • 头部巨大重复
  • 并发耗时
  • 服务器不能主动推送

兼容HTTP/1.1

  • 没有引入新的协议名 实现协议的平滑升级
  • 在应用层做了改变 基于TCP协议传输 将HTTP分解成语义和语法两个部分
  • 语义层不改变 语法改变

头部压缩

HTTP协议报文组成:Header+Body

Body部分 Content-Encoding 指定压缩方式 Header不能压缩

  • 固定字段多 比如 User Agent Accept 等 有必要压缩
  • 大量请求 报文 字段值重复 带宽被冗余数据占用 需要避免重复性
  • 字段是ASCII编码 效率低 有必要改为 二进制编码

HTTP2使用了HPACK算法来压缩头部

HPACK算法组成部分:

  • 静态字典
  • 动态字典
  • Huffman编码

客户端和服务器两端都会建立和维护字典 用长度较小的索引号表示重复的字符串

再用huffman编码压缩数据 可达到50%-90%的高压缩率

静态表编码

HTTP/2为高频出现在头部的字符串和字段建立了一张静态表 他是写入到HTTP/2中不会变化的

Index 索引 Header Value 索引对应值 HeaderName 字段名

HTTP/2头部使用二进制编码 用字符串长度分割

动态表编码

生效前提: 必须在同一个连接上 重复传输完全相同的HTTP头部

比如: 第一次发送时头部的user-agent字段数据有上百个字节 经过哈夫曼编码后 客户端和服务器都会更新自己的动态表 添加新的Index号

下次发送只发送Index号

问题:

动态表大 占用内存大 所以有 http2_max_requests的配置 限制一个连接能传输的请求数量

请求数量达到上限后 关闭HTTP/2连接来释放内存

二进制帧

HTTP/2将HTTP/1的文本格式改成二进制格式传输数据

极大提高了HTTP传输效率 二进制-> 位运算 高效解析

img

标志位:携带简单的控制信息

  • 头数据结束标志
  • 单方向发送结束
  • 流的优先级

帧头后四个字节是流标识符 组装信息

帧数据 存放的是HPACK算法压缩过后的HTTP头部和包体

并发传输

HTTP/1.1基于请求-响应模型

同一个连接中 HTTP完成一个事务(请求与响应)才能处理下一个事务

如果发出请求 响应不来 -> 队头阻塞

HTTP/2 Stream 设计 多个Stream复用一条TCP连接 达到并发的效果 提高传输量

  • 一个TCP连接包含一个或多个Stream
  • Stream里面可以包含一个或者多个Message 对应请求与响应 有由HTTP头部和包体构成
  • Message里包含一条或多个Frame Frame是HTTP/2最小单位 二进制压缩

HTTP消息由多个Frame构成 一个Frame可以由多个TCP报文构成

不同Stream的帧可以乱序发送 同一Stream内部的帧必须是严格有序的

客户端和服务器双方都可以建立Stream 客户端奇数 服务器偶数 区分

StreamID 不能复用 只能顺序递增 当Stream ID耗尽时 需要控制帧 GOAWAY关闭TCP连接

HTTP/2并发发送Stream 时 只需要建立一次TCP连接

HTTP/1.1建立连接很耗时

还可以设置优先级

服务器主动推送资源

在Nginx 中,如果你希望客户端访问 /test.html 时,服务器直接推送 /test.css,那么可以这么配置:

location /test.html { 
  http2_push /test.css; 
}

服务器主动推送的时候 使用的是偶数号Stream 服务器在推送资源时

会通过PUSH_PROMISE帧传输HTTP头部 并且通过帧中的Promised Stream ID 字段告知客户端 接下来在哪个偶数号Stream中发送包体

总结

  • 静态表+哈夫曼编码 压缩体积 建立动态表
  • Stream并发 复用TCP连接 可乱序发送
  • 可以设置值优先级
  • 服务器支持主动推送资源

问题:

  • 队头阻塞

HTTP/2基于TCP协议传输数据 TCP是字节流协议

TCP必须确认收到的字节数据 连续完整

才会返回给HTTP应用 如果前一个字节数据没有到达

后收到的字节数据只能存放在内核缓冲区

只有当1字节数据到达时 才能从内核中拿到数据

  • 一个丢失 会触发TCP重传

TCP协议本身问题 -> 拥抱光荣的进化 -> UDP -> HTTP/3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值