http2服务器推送
为什么需要服务器推送?
我们开发一个WEB页面,比如main.jsp,经常副带一个main.js,main.css文件。现有的HTTP方式是,先请求main.jsp,然后返回浏览器,再解析,发现需要依赖main.js,main.css,后面再请求main.js,main.css,这是一个通用的流程。服务器推送就是用来简化这一流程用的。
浏览器如果请求main.jsp的时候,如果有个请求头,告诉服务器,我同时需要main.js,main.css,你同时把这两个页面也给我推送过来吧。这就是服务器推送。
http2报文头压缩
http1.1 只能压缩报文体,无法压缩报文头。报文头压缩有两类,自定义的不说。另一类是RFC定义好的,比如请求头1代表get请求,2代表POST请求。这就是报文头压缩。
http2队头阻塞解决
上面两个都很好理解,比较简单,关键是这个报文头阻塞。
相信百度上有好多讲报文头阻塞的文章,也讲了http2的解决方案。关键是为什么这种分流分帧的方式能解决报文头阻塞。
先说说为什么会有报文头阻塞。
http1.0的时代,http每发一个请求就会关闭当前连接,再发请求,要重新创建连接。但是http1.0支持keep-alive。设置这参数后,不会当前连接。可以对这个连接进行复用。
http1.1默认设置连接为keep-alive。虽然能达到复用,但是如果页面上依赖的资源非常多,而每个连接是串行的,什么意思了,就是发送请求前,必须先得到上个请求的响应。就是请求1->响应1->请求2->响应2。按这种模式进行。有人就会说了,那我可以并发呀,我创建多个连接。这样就可以同时发送请求1与请求2了。OK,这样确实可以,浏览器也是这么干的。一般给每个域名下的最多同时创建6个请求。但这样带来的问题是,服务器本来并发600,支持600人,现在只能同时支持100人了。
http1.1管线技术。为了解决单个连接只能串行的问题。出现管线技术。我允许浏览器在单个连接上发送多个请求,而不用等待响应。就是请求1->请求2->响应1->响应2。但是这种模式也有问题,如果响应1很慢,那就会阻塞响应2。这就是队头阻塞。那有人会说,响应1既然很慢,为什么不把响应2先返回了。这里有个问题,是不能先返回响应2。如果我先给你响应2了,浏览器怎么知道这个响应是对应请求2的了?如果想让浏览器知道这个响应对应于某个请求,只能修改报文头,那就得很涉及修改http协议了,这就是http2干的活了。
http2是怎么解决这个问题的了,将服文分帧,发送的内容变得更小了。类似于tcp。将整个报文分成一个流,一个流里面分成若干个帧,比如报文头帧,数据帧。这样浏览器就能区分服务端返回的哪个请求对应的响应了。