http基础
http简介
- 在应用层负责生成针对目标服务器的HTTP请求报文。
- http无状态所以出现了cookie
- 发送一次断开一次链接,所有出现了keep-alive持久连接。
- 然后在这个基础上出现了管线化,同时发送多个请求。
http协议历史
http2.0参考[一文读懂 HTTP/2 特性 - 知乎 (zhihu.com)](
- http1.0
- 基础协议
- 仅支持GET、POST
- http1.1
- 缓存策略 cache-control E-tag 等
- 支持长连接 Connection: keep-alive,一次TCP 连接多次请求
- 断点续传,状态码 206
- 支持PUT、DELETE, 由此可用于Restful API(url请求对应服务器上的唯一资源)
- http2.0
- header头部压缩
- 多路复用, 一次TCP链接可以有多个http请求并行
- 服务器推送
- 二进制分帧
关键点解析
连接数限制
- http征求意见稿rfc2616规定浏览器对于一个域名,同时只能有 2 个连接。而PV、UV、ajax请求、JS逻辑错误、页面资源加载等等都会触发上报,同时2个连接明显不够用,可能会造成网络阻塞,上报延迟。
- 后来在修正稿rfc7230中去掉了这个限制, 只规定了限制数量,但并未指定具体数字,浏览器也实际放宽了限制。比如Chrome是同时6个连接(出于公平和安全考虑,如果不限制数量,理论上一个客户端就能占用大量服务器资源,甚至压垮服务器)。
- 然而,一个请求独占一个连接,有时候6个连接也是不够用的。
http2.0优化点
多路复用
- 那如何突破限制呢?有一个绝招:就是升级到http2, 利用h2的多路复用特性。 一个连接上打开多个流,还可以双向数据传输,轻松突破6路并行限制。
头部损耗&头部压缩
突破6路限制就够了吗?我们再来看看另一个很容易被忽略的部分:http头部损耗。
- http请求中,每次请求都会包含一系列的请求头来描述请求的资源和特性等。而头部没经过任何压缩,每次请求都要占用200-800个字节,如果带上一个比较大的cookie,甚至会超过1K;
- 而我们实际的日志数据大小仅仅只有10 - 50字节,头部消耗占了90%以上;
- 另外,据Htpp Archive统计数据,平均每个页面上百个请求,越来越多的流量消耗在头部;
- 最致命的是,UserAgent等信息不会频繁变动,每次请求都传输是一种严重的浪费。
再次利用h2头部压缩。先来看看采用h1和h2的效果对比。 h1下请求大小295 字节, 而h2仅仅只有18 字节,大小只有区区16分之一,请求时间也从6ms降低到了4毫秒。
太神奇了,来快速地过一下http2头部压缩是如何实现的:
- 首先协议里预设了一个静态字典,用来表示常用的头部字段,比如图中,2就是 method get. 以前需要把完整的key-value对发过去,现在只需要把一个数字发过去,大小大幅缩小。
- 其次,客户端和服务端会共同维护一个动态表,动态表用来干啥呢?举个例子,比如useragent, 每个用户的useragent值是不一样的,没法放到静态表中去约定。但是对于同一个用户会话,useragent是不会改变,这样的值,就由客户端和服务端协商决定存入动态表,这样第一次传输过去之后,以后就只需要传入动态表中的一个编码就行了,图中的62和63就是这样的情况。连接中发送的请求越多,就越能丰富动态表中的值,越到后面,请求性能越好(佐证了域名散列的方式不可取)。
- 还有一类情况,值总是变来变去,也没法保存到动态表中。这时候,只能直接压缩了。在h2中采用的是Huffman压缩算法,能把数字或字符最短压缩到5个字节,最大压缩率是37.5%。
其他优化
- 采用http 204返回无响应体的response;
- 采用post请求合并多条日志,共用请求头;
- 错误调用堆栈中经常会出现很多的文件url,占了不少空间,可以考虑将他们抽取成一个变量; 时间关系志采集部分就到此为止。
常用的Header头
Request Header
- Accept 浏览器可接收的数据格式
- Accept-Encoding 浏览器可接收的压缩算法,如gzip
- Accept-Language 浏览器可接收的语言,如zh-CN
- Connection: keep-alive 一次TCP链接可以重复使用
- cookie 浏览器自己带过去
- Host 请求的域名
- User-Agent UA浏览器信息
- Content-type 发送的数据格式,如application/json
Response Header
Content-type 返回数据的格式,如application/json
Content-length 返回数据的大小,多少字节
Content- Encoding 返回数据的压缩算法,如gzip
Set-Cookie 服务端设置浏览器cookie
缓存
强制缓存
- 客户端缓存策略, 客户端来控制是否缓存
- 不会向服务器发送请求,状态码200, 直接从缓存中读取资源,在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且Size显示from disk cache或from memory cache两种(灰色表示缓存)
- Expires:返回过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。已被Cache-Control替代
- Cache-Control:
- max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再加载资源,就会命中强缓存。两者同时存在,2会覆盖1
- no-cache,不接受客户端缓存,中间缓存服务器必须向服务器确认有效性。
- no-store, 不接受客户端缓存+不接受中间缓存服务器缓存+不接受协商缓存
- private, 只允许客户端缓存+不接受中间缓存服务器缓存
- public, 允许客户端缓存+不接受中间缓存服务器缓存
协商缓存(对比缓存)
- 服务端缓存策略, 服务端来控制是否缓存
- 会向服务器发送请求, 状态码304,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;
- Last-Modified:服务器返回资源最后更改时间(单位是秒),浏览器会保存下来下次请求放到If-Modified-Since里,服务器在做对比,相同则命中协商缓存。
- If-Modified-Since:浏览器请求带上Last-Modified,服务器再做对比,则命中协商缓存。
- Etag: 将资源一字符串形式做唯一性标志。资源有变化, 服务器会对每份资源分配对应的ETag值。资源更新的时候,ETag也更新。
- If-None-Match: 浏览器请求带上Etag,服务器再做对比,相同则命中协商缓存。
- Last-Modified对比Etag
- 优先使用Etag
- 精度上Last-Modified劣于Etag,如果一秒内改变多次,那么这样其实并没有体现出改变,但是Etag可以反映出来。
- 性能上Last-Modified优于Etag,只需要记录时间,Etag需要服务器通过算法来计算出一个hash值。服务器优先考虑Etag。
304缓存的原理
- 客户端请求一个页面,服务器返回页面并给页面加上一个Etag,客户端展现该页面并将页面联通Etag一起缓存。客户端再次发送带有附加条件的请求时(If-match,If-Node-Match,If-Modefined-Since)服务端允许请求验证,但是资源并未发生改变,可以使用客户端缓存的资源,返回的状态码,此时不返回任何实体信息,和重定向没有关系。
强制、协商对比
- 共同点: 都是从客户端缓存中读取资源;
- 不同点:强缓存不会发请求,协商缓存会发请求。
用户行为对浏览器缓存的控制
- 地址栏访问:将会触发浏览器缓存机制,正常验证本地缓存是否过期,或者协商缓存
- F5刷新:浏览器会设置max-age=0,跳过强缓存判断,进行协商缓存判断,服务器会检查文件新鲜度,返回结果可能是304,也可能是200
- Ctrl+F5强刷:跳过强缓存和协商缓存,直接从服务器拉取资源。直接请求新资源
常见状态码
- 100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
- 200 OK 正常返回信息
- 201 Created 请求成功并且服务器创建了新的资源
- 202 Accepted 服务器已接受请求,但尚未处理
- 206 断点续传 (http1.1开始支持)
- 301 Moved Permanently 永久重定向请求的网页已永久移动到新位置。
- 302 Found 临时性重定向。
- 303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
- 304 Not Modified 自从上次请求后,请求的网页未修改过。
- 400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
- 401 Unauthorized 请求未授权。
- 403 Forbidden 禁止访问。
- 404 Not Found 找不到如何与 URI 相匹配的资源。
- 500 Internal Server Error 最常见的服务器端错误。
- 503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
http与https
http的不足
- 通信使用明文,内容可能被窃听;
- 不验证通信方身份,有可能遭遇伪装;
- 无法证明报文的完整新,有可能已被篡改。
Https(SSL)方案
- 用安全套接层(SSL)建立安全通信线路后,http就可以被加密了,
- 其实就是将HTTP和TCP直接通信换成HTTP—>SSL—>TCP。
- 和ssl结合使用的http成为https:HTTP+加密+认证+完整性保护=HTTPS