菜单

HTTP2 Server Push的商讨

2019年10月5日 - Json

HTTP2 Server Push的研究

2017/01/05 · 基本功技巧 ·
HTTP/2

初稿出处:
AlloyTeam   

主题材料:加载三个页面所需的能源,须要频仍呼吁。比方加载index必要必要二遍:index.html、index.js、index.css。

1,HTTP2的新本性。

有关HTTP2的新特点,读着可以参照他事他说加以考察小编事先的小说,这里就不在多说了,本篇小说主要讲一下server
push这些天性。

HTTP,HTTP2.0,SPDY,HTTPS你应有精通的一些事

 

消除思路:Server在收受到加载index诉求时,同有时候重临index.html、index.js、index.css。

2,Server Push是什么。

简短来说正是当顾客的浏览器和服务器在确立链接后,服务器主动将有些能源推送给浏览器并缓存起来,那样当浏览器接下去诉求这一个能源时就平素从缓存中读取,不会在从服务器上拉了,进步了速率。举三个事例正是:

一经贰个页面有3个财富文件index.html,index.css,index.js,当浏览器央求index.html的时候,服务器不仅仅再次来到index.html的从头到尾的经过,同不时候将index.css和index.js的内容push给浏览器,当浏览器后一次恳请那2四个文本时就可以间接从缓存中读取了。

Client:

3,Server Push原理是什么。

要想掌握server
push原理,首先要明了一些定义。大家明白HTTP2传输的格式并不像HTTP1使用文本来传输,而是启用了二进制帧(Frames)格式来传输,和server
push相关的帧主要分为这几系列型:

  1. HEADE汉兰达S
    frame(央求重临头帧):这种帧首要辅导的http央求头新闻,和HTTP1的header类似。
  2. DATA frames(数据帧) :这种帧寄放真正的数量content,用来传输。
  3. PUSH_PROMISE
    frame(推送帧):这种帧是由server端发送给client的帧,用来代表server
    push的帧,这种帧是落成server push的关键帧类型。
  4. RST_STREAM(撤废推送帧):这种帧表示诉求关闭帧,轻巧讲正是当client不想接受某个财富依旧接受timeout时会向发送方发送此帧,和PUSH_PROMISE
    frame一齐利用时表示拒绝只怕关闭server push。

Note:HTTP2.0连锁的帧其实满含10种帧,就是因为底部数据格式的改观,才为HTTP2.0带来相当多的特征,帧的引进不唯有利于压缩数量,也可能有支持数据的安全性和可信传输性。

叩问了有关的帧类型,下边就是现实server push的达成进度了:

  1. 由多路复用大家得以领略HTTP第22中学对于同二个域名的央浼会选用一条tcp链接而用分化的stream
    ID来分别各自的呼吁。
  2. 当client使用stream
    1央浼index.html时,server平常处理index.html的乞请,并能够识破index.html页面还将要会呈请index.css和index.js。
  3. server使用stream 1发送PUSH_PROMISE
    frame给client告诉client作者那边能够选取stream 2来推送index.js和stream
    3来推送index.css能源。
  4. server使用stream 1寻常的发送HEADEENVISIONS frame和DATA
    frames将index.html的内容重回给client。
  5. client接收到PUSH_PROMISE frame得知stream 2和stream
    3来接收推送能源。
  6. server获得index.css和index.js便会发送HEADEMuranoS frame和DATA
    frames将财富发送给client。
  7. client得到push的财富后会缓存起来当呼吁这么些财富时会从一直从从缓存中读取。

下图表示了整个流程:

图片 1

Link: </css/styles.css>; rel=preload; as=style, </js/scripts.js>; rel=preload; as=script, </img/logo.png>; rel=preload; as=image

4,Server Push怎么用。

既然server
push这么神奇,那么大家怎么运用啊?怎么设置服务器push哪些文件呢?

先是实际不是有所的服务器都扶助server
push,nginx近期还不协助那一个性子,可以在nginx的法定博客上得到认证https://www.nginx.com/blog/http2-r7/,可是Apache和nodejs都早已支撑了server
push那叁个个性,必要证美赞臣(Meadjohnson)些的是server
push那么些特性是依据浏览器和服务器的,所以浏览器并不曾提供相应的js
api来让客商一直操作和操纵push的从头到尾的经过,所以只可以是通过header音讯和server的铺排来促成具体的push内容,本文首要以nodejs来证实具体怎么样利用server
push这一天性。

安不忘虞职业:下载nodejs
http2
支撑,本地运营nodejs服务。

1. 第一大家运用nodejs搭建基本的server:

JavaScript

var http2 = require(‘http2’);   var url=require(‘url’); var
fs=require(‘fs’); var mine=require(‘./mine’).types; var
path=require(‘path’);   var server = http2.createServer({   key:
fs.readFileSync(‘./zs/localhost.key’),   cert:
fs.readFileSync(‘./zs/localhost.crt’) }, function(request, response) {
    var pathname = url.parse(request.url).pathname;     var realPath =
path.join(“my”, pathname);    //这里安装自个儿的文件名称;       var
pushArray = [];     var ext = path.extname(realPath);     ext = ext ?
ext.slice(1) : ‘unknown’;     var contentType = mine[ext] ||
“text/plain”;       if (fs.existsSync(realPath)) {  
        response.writeHead(200, {             ‘Content-Type’:
contentType         });  
        response.write(fs.readFileSync(realPath,’binary’));       } else
{       response.writeHead(404, {           ‘Content-Type’: ‘text/plain’
      });         response.write(“This request URL ” + pathname + ” was
not found on this server.”);       response.end();     }   });  
server.listen(443, function() {   console.log(‘listen on 443’); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var http2 = require(‘http2’);
 
var url=require(‘url’);
var fs=require(‘fs’);
var mine=require(‘./mine’).types;
var path=require(‘path’);
 
var server = http2.createServer({
  key: fs.readFileSync(‘./zs/localhost.key’),
  cert: fs.readFileSync(‘./zs/localhost.crt’)
}, function(request, response) {
    var pathname = url.parse(request.url).pathname;
    var realPath = path.join("my", pathname);    //这里设置自己的文件名称;
 
    var pushArray = [];
    var ext = path.extname(realPath);
    ext = ext ? ext.slice(1) : ‘unknown’;
    var contentType = mine[ext] || "text/plain";
 
    if (fs.existsSync(realPath)) {
 
        response.writeHead(200, {
            ‘Content-Type’: contentType
        });
 
        response.write(fs.readFileSync(realPath,’binary’));
 
    } else {
      response.writeHead(404, {
          ‘Content-Type’: ‘text/plain’
      });
 
      response.write("This request URL " + pathname + " was not found on this server.");
      response.end();
    }
 
});
 
server.listen(443, function() {
  console.log(‘listen on 443’);
});

这几行代码正是轻便搭建二个nodejs
http2服务,打开chrome,我们能够看出全体央求都走了http2,同有的时候候也足以表明多路复用的特色。

图片 2

那边供给注意几点:

  1. 创立http2的nodejs服务必需时依据https的,因为以往主流的浏览器都要支持SSL/TLS的http2,证书和私钥能够团结通过OPENSSL生成。
  2. node http2的连锁api和符合规律的node httpserver一样,能够一贯动用。

  3. 设置我们的server push:

JavaScript

var pushItem = response.push(‘/css/bootstrap.min.css’, {        request:
{             accept: ‘*/\*’        },       response: {
            ‘content-type’: ‘text/css’      } });
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

1
2
3
4
5
6
7
8
9
var pushItem = response.push(‘/css/bootstrap.min.css’, {
       request: {
            accept: ‘*/\*’
       },
      response: {
            ‘content-type’: ‘text/css’
     }
});
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

小编们设置了bootstrap.min.css来经过server
push到大家的浏览器,大家得以在浏览器中查看:

图片 3

能够见到,运维server push的财富timelime非常的慢,大大加快了css的获取时间。

此间供给小心下边几点:

  1. 大家调用response.push(),就是相当于server发起了PUSH_PROMISE
    frame来报告浏览器bootstrap.min.css将会由server push来收获。
  2. response.push()再次回到的对象时二个正规的ServerResponse,end(),writeHeader()等艺术都得以健康调用。
  3. 那边一旦针对有个别能源调用response.push()即发起PUSH_PROMISE
    frame后,要做好容错机制,因为浏览器在下一次恳请那么些财富时会且只会等待那几个server
    push回来的能源,这里要盘活超时和容错即下边包车型大巴代码:
  4. JavaScript

    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {        response.writeHead(404, {           
    ‘Content-Type’: ‘text/plain’        });        response.end(‘request
    error’); }   pushItem.stream.on(‘error’, function(err){
        response.end(err.message); });   pushItem.stream.on(‘finish’,
    function(err){    console.log(‘finish’); });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {
           response.writeHead(404, {
               ‘Content-Type’: ‘text/plain’
           });
           response.end(‘request error’);
    }
     
    pushItem.stream.on(‘error’, function(err){
        response.end(err.message);
    });
     
    pushItem.stream.on(‘finish’, function(err){
       console.log(‘finish’);
    });

    地点的代码你或然会意识繁多和例行nodejs的httpserver不一样样的东西,那便是stream,其实全部http2都以以stream为单位,这里的stream其实能够掌握成二个伸手,更加的多的api能够参谋:node-http2

  5. 提及底给大家推荐一个鬼子写的极度服务http2的node
    server有兴趣的能够品味一下。https://gitlab.com/sebdeckers/http2server

Server
Apache: FilesMatch、H2PushResource
Nginx:不支持

5,Server Push相关难点。

  1. 咱俩领略今后我们web的财富平时都以位于CDN上的,那么CDN的优势和server
    push的优势有啥分歧吧,到底是哪些异常快吧?这几个主题素材作者也一贯在商讨,本文的连锁demo都只可以算做多个示范,具体的线上施行还在实行中。
  2. 出于HTTP2的有的新特性举例多路复用,server
    push等等都是基于同四个域名的,所以那恐怕会对大家事先对于HTTP1的一部分优化措施譬如(能源拆分域名,合併等等)不断定适用。
  3. server
    push不仅可以够作为拉取静态财富,大家的cgi供给即ajax诉求一样能够接纳server
    push来发送数据。
  4. 最健全的结果是CDN域名帮助HTTP2,web server域名也还要补助HTTP2。

 

参考资料:

  1. HTTP2官方正式:https://tools.ietf.org/html/rfc7540
  2. 维基百科:https://en.wikipedia.org/wiki/HTTP/2_Server_Push
  3. https://www.nihaoshijie.com.cn/index.php/archives/651

    1 赞 1 收藏
    评论

图片 4

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图