网络http1.0/http1.1/http2 的迭代过程

首先,已知网络定义的标准为OSI七层模型: 物理层,数据链路层,网络层,传输层,会话层,表示层,应用层.

但实际的标准为TCP/IP 五层模型

在这里插入图片描述

HTTP的发展史:

  • 1996年,1.0规范:RFC 1945诞生;
  • 1999年,1.1规范:RFC 2616诞生;
  • 2015年,2.0规范:RFC 7540/7541诞生,

实际目前主流还是http1.1版本.

HTTP报文结构: 起始行 + header + body

  • 起始行:标记 这是请求(http request)还是响应(http response)
  • header :KV键值结构,可存储多个KV.
  • body:一个字符串

get类型的请求,请求体是空的;
而对于网页来说,响应体就是一个html串,可以让浏览器去解析显示


HTTP的1.0版本


HTTP:超文本传输协议,作为明文传输协议,不是2进制的协议.

客户端发出TCP连接后,在连接上发出http request 到服务器,服务器返回一个http response,然后再关闭连接.


(1)HTTP的性能问题: 连接的建立、关闭比较耗时,对网页来说,除页面本身的html请求,页面中的js、css、javaScript、img…这些静态资源,都是一个一个的http请求, 就目前的互联网页面,一个网页至少有几十个资源文件,要是每个请求都开出一个TCP连接就非常耗时了,虽然说可以同时开多个连接,然后并发形式发出请求,但连接数是有限的.
(2)HTTP的服务器推送问题:客户端不发出请求的时候, 服务器不会主动给客户端推送消息.


为解决第一个性能问题:

  • 客户端就在 http请求头加了字段Connection:keep-Alive 服务器收到该配置的请求后,处理这个请求之后就不会关闭连接,也在http的响应头中加入该字段,等待客户端在此连接线路中发送下一个请求.
  • 但是此时带给服务器的问题就是:连接数有限,若每个连接都设置了Connection:keep-Alive ,都不及时关闭,越来越多…服务器的可用连接数不足. 所以说服务器就设置了 keep-Alive timeout参数,在设定的时间之后,此连接上没有新的请求发来时,这个连接就会关闭.
  • 连接复用的新问题,在之前的版本中一个连接仅发送一个请求得到一个响应,服务器处理后就把连接关闭; 此时客户端就会明白连接的请求处理结束, 但此时即使一个请求处理结束后也不关闭连接,那么客户端如何得知http请求处理结束了呢? / (如何确认接收的是完整数据包呢?) 实际上:在http 的响应头中就会返回一个Content-Length:xxx, 该属性可告诉客户端的响应体一共多少字节,客户端收取完成后就知道自己的收据接收完毕了.

HTTP的1.1版本


缼省连接复用

  • HTTP的1.1版本时,这个连接复用 就作为一个缼省的属性,[即使不在请求头中加属性Connection:Keep-Alive,服务器处理完请求后也不关闭连接].
  • 当然不想用这个连接复用属性,也可以使用Connection:Close进行关闭.

数据分块chunk

在之前版本中的Content-Length有这样的问题: 若服务器返回的数据作为动态语言生成的内容,那么就得自己计算Content-Length, 对对服务器来说比较耗时.

所以HTTP1.1使用了Chunk机制, 即在响应头中加入Transfer-Encoding:chunked属性,目的是通知客户端–>响应体被分为一块一块的,每个数据块之间有间隔符,这些块的结尾具有标记,那么即使不设置Content-Length时,客户端也可以根据该标记判断到响应体的数据是否已经接收完毕.

比如这个非常经典的案例:
响应中包含了4个chunk,数字25(16进制)表示第一个chunk的字节数,
1C(16进制)表示第二个chunk的字节数;数字3 … 8…,
最终数字0表示整个响应的数据完毕

HTTP/1.1 200 OK
Content-Type: text/plain
  Transfer-Encoding: chunked
  25
This is the data in the first chunk
  1C
and this is the second one 
  3
con
  8
sequence
  0      

管道传输Pipeline机制

虽然连接复用机制好用一点,但是在同一个连接之上,请求是串行交互的,客户端发送一个请求后,收到响应,然后发出下一个请求,再进行回应.这就是传统的串行化方式交流,并发度过低.

所以在HTTP1.1时,优化使用了PipeLine管道机制,在同一个TCP上面,即使这个请求的响应还没回来,当然还可以发送其他的请求,提高了请求的效率.
在这里插入图片描述
但是这样的机制又产生 队头阻塞问题[Head-of-line Blocking]

  • 比如客户端发请求时顺序是1,2,3 发出去的, 虽然说咱们服务器可以并发处理请求, 但是客户端接收响应的顺序也必须是 1, 2, 3;这样才能保证请求得到的是自己对应的响应数据;.

  • 可是一旦某个请求的响应出现了延迟阻塞,那么后面的响应也会被阻塞.


性能优化

(1)由于队头阻塞问题,管道通信PipeLine不好用,
(2)对于同一个域名,浏览器限制只可以开6-8个连接,但是一个网页获取要发几十个请求,怎么提升性能;

此时就需要来优化性能了;

(1)spriting技术: 主要用于小图标.

假设某个网页,需要从服务器加载很多的小图标,那就可以在服务器中将这些小图标拼成一个大图,再通过JS/CSS,从大图中截取需要的小图标进行使用.

(2)内联:也是主要用于小图标.

将图片的原始数据存入CSS文件,
比如:

.iconw{
        background: url(data:image/png;base64,<data>) no-repeat;
}

(3)JS拼接

将大量比较小的JS文件合并为一个文件且压缩打包,让浏览器在一个请求中就可以下载结束;

(4)请求分片技术

由于一个域名,浏览器就限制它开6-8个连接,对于网站开发者来说,想要提升页面加载速度,一个方法就是多提供几个域名,逃避浏览器的限制问题; 比如目前的CDN技术, (img,js,css)都可以存到CDN上面,可做一批CDN的域名,提升页面加载并发度.


服务器如何做到主动推送消息


对于web流程来看,http1.0和http1.1版本 都无法达到 服务器主动推送消息; 但是在实际开发中又存在这样的需求.可以试试这几种方法:

(1)采用客户端定时的轮询请求

每隔一段时间,客户端发出请求, 服务端有了新消息就响应回去, 但是这种方式会增加服务器的压力.

(2)HTTP长轮询

客户端发出HTTP请求,若服务端恰好有新消息则响应即可, 若没有,服务器就会保持这个连接,客户端那边一直等待.
如果超出某个设定的时间,服务器还没有消息,那么服务器就响应空消息,客户端停手=>关闭连接.

(3)HTTP stream流

服务端采用分块发送Transfer-Encoding: chunked机制,不断发送数据块,即响应不停止.


断点下载
当客户端从服务器下载文件时,若下载到一半时连接中断,再次新建连接之后,客户端就可以从上次断开的位置继续下载.

客户端在下载时就顺便记录下载的数据量大小, 一旦连接中断,那么重新连接之后,在请求头处 就可以加上Range:first offset - last offset,指定从指定的offset下载到指定的offset ,
服务器仅需要响应first->last区间的数据即可.


HTTP的2版本


由于1.1的pipeline管道传输机制有队头阻塞问题,那么协议层面的SPDY协议就出现了,进而优化出现了HTTP2版本.


HTTP2也是兼容了HTTP1.1, 在它的上面套了一个HTTP1.1协议, 可以这么看:HTTP2处于HTTP1.1和TCP协议之间.

在这里插入图片描述


HTTP的优化: 2进制分帧,避免了队头阻塞问题
具体:
(1) 对每个域名, 客户端与服务器之间仅维护一条TCP连接;
(2)在将HTTP1.1的字符格式报文发给TCP之前,中间的 HTTP2就会把它转为2进制,分为多个帧(数据块)发送到TCP.
请求响应过程中进行拆包组包即可

在这里插入图片描述

二进制分帧机制采用之后,在TCP层面,看起来是串行的,但是在HTTP通信层面来看实际就是并发地发放出去,并发接收响应,没有http1.1那种pepeline的限制 ;
比如请求 A,B,C 虽然按顺序发出去的,但响应的消息可以不按顺序返回.
在这里插入图片描述


并没有彻底解决队头阻塞问题,只是从细化了为帧, 降低了队头阻塞发生的频率;
由于TCP协议是先进先出的,若队头的第一个帧 在网络上被阻塞(或丢包),那么服务器就会一直等待这个数据帧,若它不来,则后面的包都不会被成功接收.

请求1的响应1为什么迟迟不来呢?

  • (1)服务器对于请求1处理很慢;
  • (2)服务器对于请求1 处理及时,但是网络传输过慢;

(1)的问题:当前的请求2与请求3响应分帧后,先于请求1的响应发出;那么请求2/请求3的响应就不会被请求1阻塞,避免了队头阻塞问题.
(2)的问题:若请求1的第一个帧处于队头,则及时二进制分帧也无法解决队头阻塞问题.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小智RE0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值