比较http1,http2
http1
- 队头阻塞(Head-Of-Line Blocking)
- 无状态特性 — 阻碍交互
- 明文传输 — 不安全性
- 不支持服务端推送
-
队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。
- Chrome有个机制,对于同一个域名,默认允许同时建立 6 个 TCP持久连接,如果在同一个域名下同时有10个请求发生,那么其中4个请求会进入排队等待状态,直至进行中的请求完成。这样的问题的话,
- 解决办法
- 可以使用多个域名加载资源解决
- 合并资源,减少请求数量。使用精灵图;小文件直接合并在文件里,css、js、图片转 base64合并到html
-
- 无状态特性
- 无状态是指协议对于连接状态没有记忆能力,header里就会有很多信息,会发送很多重复的信息
-
- 明文传输(相对不安全)
-
- 不支持服务器推送消息
http2
-
- 二进制传输, 二进制协议解析起来更高效
-
-
Header 压缩
- 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送。第一个请求发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销
- 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
- 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
-
-
- 多路复用
- 同域名下所有通信都在单个连接上完成。
- 单个连接可以承载任意数量的双向数据流。
- 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。
-
-
服务器推送
HTTP2还在一定程度上改变了传统的“请求-应答”工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。比如,在浏览器刚请求HTML的时候就提前把可能会用到的JS、CSS文件发给客户端,减少等待的延迟,这被称为"服务器推送"
-
http2 是快了,但也可能会有其他问题,比如请求太多了,会导致服务器瞬时访问量变大,服务器压力大。数据处理不好,还可能会timeout
强缓存和协商缓存
强缓存
- 强缓存就是读取本地内容不请求服务器资源 设置响应头 'Cache-Control': 'max-age=xxx' ,只要在时间范围内就会读取本地资源。
- 缺点就是服务器资源更新后,客户端是不知道的,导致获取不到最新资源
协商缓存
Last-Modified
- 文件的响应头有
Last-Modified字段,再次请求时他的值会以If-Modified-Since字段加在请求头,服务器收到请求头时,比较If-Modified-Since和资源的更新时间,如果相同就返回304, 不同 就返回最新资源。 - 缺点就是: 协商缓存无法解决服务器资源命名不变但是文件变了,浏览器不会去更新这个文件,因为只判断更新时间。
etag
- 查了下, nginx 下的etag 是由 last_modified 与 content_length 拼接而成的字符串。为什么不用Md5呢,原因就拼接时间和长度便于计算,不会特别耗 CPU。利用摘要算法生成 (MD5, SHA128, SHA256) 需要慎重考虑,因为他们是 CPU 密集型运算,耗费cpu。
PS:分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败。分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样)。
写在结尾:欢迎批评指正,持续更新中