Skip to content

Latest commit

 

History

History
158 lines (149 loc) · 7.5 KB

http笔记.md

File metadata and controls

158 lines (149 loc) · 7.5 KB

http学习笔记

http1.1

http几个类别:
1.text
2.image
3.audio/video
4.application:application/json、application/javascript、application/pdf
encoding type:
1.gzip
2.deflate:zlib压缩方式
3.br:一种专门为http优化的新压缩算法
accept字段标记的是客户端可理解的MIME type,可以用逗号做分割符列出多个类型
让服务器有更多的选择余地,例如下面这个
Accept: text/html,application/xml,image/webp,image/png
Accept-Encoding标记的是客户端支持的压缩格式
服务器的Content-Encoding表示实际使用的压缩格式
Accept-Language标记了客户端可理解的自然语言,也允许用,做分隔符列出多个类型
Accept-Language: zh-CN, zh, en
服务器端Content-Language: zh-CN
字符集在http里使用的请求头字段是Accept-Charset,但是响应头里没有对应的Content-Charset,
而是在Content-Type字段的数据类型后面用charset=xxx来表示
q设置优先级,quality factor
Accept: text/html,application/xml;q=0.9,*/*;q=0.8
表示浏览器最希望使用的是html文件,权重是1,其次是XML文件,权重是0.9,任意数据权重是0.8
vary表示服务器端采用了客户端的哪个字段,不是每个客户端的accept选项服务器都会采用
浏览器最多会有六个连接并发执行,是rfc的规定。
http协议对body大小没有限制,一般都是框架自己的限制
客户端accept-encoding填写了gzip,但是服务端不一定返回的报文就是gzip的,
要看它的content-encoding,不一定是压缩的。
服务器端很可能无视很多字段,http1.1里唯一强制要求的就是host字段,其他都不是必须的。
客户端发送的报文,也需要要填content-*,表示自己的报文属性,如果body是空就可以不携带了
chunk场景http只有一个包,客户端发了请求之后一直等。不过对于这个包在tcp层可能是多个包
流式场景也就是所谓的动态数据,主要用于不知道总长度多长的场景
多段数据每一段都需要指定content type是因为每段数据可能类型不同
cdn一般是缓存整个源文件,而不是只存一部分(虽然客户端可能range来取)
早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;
HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;
服务器会发送“Connection: keep-alive”字段表示启用了长连接;
报文头里如果有“Connection: close”就意味着长连接即将关闭;
过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;
connetion字段还有一个取值是Connetion:Upgrade,
配合状态码101表示协议升级,例如从http切换到web socket
域名分片(domain sharding)技术是解决客户端并发的问题,
可以创建更多的连接,并不能减轻服务器的压力(限于http1.1)
“队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”技术缓解。
http是“半双工”,只能一来一回发送数据,这就是队头阻塞的根源,举例说明:
有两个http请求 a和b,每个请求都是由10个tcp数据包构成的,
在同一个复用的tcp连接上,a先于b发出,都发送到同一台服务器,
但是在服务端 当a接收到5个tcp数据包的时候,b的10个tcp数据包已经接受完成了
在http协议的层次是不关心tcp包的,请求会按照先后顺序排队,
所以服务器会先处理a再处理b,这就是队头阻塞。
根据请求的频繁程度来选择连接模式。一次性的请求用短链接,频繁与服务端交互的用长连接。
1,服务器端设置keepalive_timeout表示多长时间没有数据则关闭连接。
2,服务器端设置keepalive_requests,表示该连接上处理多少个请求后关闭连接。
3,服务器端设置最大连接数,当连接达到上限之后拒绝连接,也可以采用限流措施等。
4,客户端设置keepalive_requests,表示该连接上发送多少个连接后关闭连接。
5,客户端设置keepalive_timeout,表示多长时间没有数据发送则关闭连接。
6,客户端设置响应超时后重试次数,当次数达到上限后关闭连接。
http协议无法明确的标识出某个rsp是哪个req的。
如果服务端不等待上一个req-rsp结束就发出另一个rsp,那么客户端无法区分收到的数据。
单连接上的多路复用也是基于请求-响应机制的,
虽然一个连接上同时流动着多个req-rsp的数据,但是应用层协议有序号可以区分出rsp是哪个req的。
http1.1会默认开启keep-alive,即隐含的会有头字段connection:keep-alive,
也可以显式的设置keep-alive 
http1.1的报文是顺序发出然后顺序响应接收的
根据http请求应答模式,同一个连接中,客户端发送一个请求,
在收到该请求的响应前,客户端是不能在该连接上发送下一个请求的
F5的强制刷新其实是客户端发了一个Cache-Control: no-cache
F12里如果看到from disk cache,说明用的是浏览器本地缓存

http其他

HTTP/2 必须先发送一个“连接前言”字符串,然后才能建立正式连接;
HTTP/2 废除了起始行,统一使用头字段,在两端维护字段“Key-Value”的索引表,使用“HPACK”算法压缩头部;
HTTP/2 把报文切分为多种类型的二进制帧,报头里最重要的字段是流标识符,标记帧属于哪个流;
流是 HTTP/2 虚拟的概念,是帧的双向传输序列,相当于 HTTP/1 里的一次“请求 - 应答”;
在一个 HTTP/2 连接上可以并发多个流,也就是多个“请求 - 响应”报文,这就是“多路复用”。
HTTP/3 基于 QUIC 协议,完全解决了“队头阻塞”问题,弱网环境下的表现会优于 HTTP/2;
QUIC 是一个新的传输层协议,建立在 UDP 之上,实现了可靠传输;
QUIC 内含了 TLS1.3,只能加密通信,支持 0-RTT 快速建连;
QUIC 的连接使用“不透明”的连接 ID,不绑定在“IP 地址 + 端口”上,支持“连接迁移”;
QUIC 的流与 HTTP/2 的流很相似,但分为双向流和单向流;
HTTP/3 没有指定默认端口号,需要用 HTTP/2 的扩展帧“Alt-Svc”来发现。
QUIC 之所以解决了队头阻塞,是基于UDP的乱序,无连接,以包为单位进行传出的特性,
即当发生丢包时,当前流中对应的请求或应答就彻底“丢失”了,
之后只需要通过在UDP基础实现的“可靠传输”功能,重传就好了,
这样就避免了接收端死等尚未接收到的数据的“干着急”状态;
quic里的另一个关键是流概念,它和http/2的一样,把多个请求响应解耦,互不干扰。
这样在上层应用层和下层的传输层就都没有了队头阻塞,但因为丢包而重传该等还是会等,只是不会影响其他的流。
cdn一般有专用的高速网络直连源站,或者是动态路径优化,所以动态资源通过cdn回源要比通过走公网回源速度快很多。
websocket主要解决动态数据主动推送的场景(站内信推送,评论推送之类),http主要是pull模式。
http报文head里不能有空行,如果有空行,那么空行后的数据就会被认为是 body,导致 header缺失
http get方法也可以有请求体,在body里传递数据