关于HTTP2以及使用Nginx来部署一个HTTP2的服务

HTTP2相较与HTTP1.1的优势

  • 能够进行信道复用
  • 分帧传输
    • 每一帧都有一个上下文的联系
    • 我们传输的HTTP请求的数据不一定要按照连续的顺序发送
    • 分成不同的帧,然后一起进行发送
    • 数据接收完成之后,根据帧信息的顺序进行组合
    • 最后拿到完整的数据
    • 因为分帧传输,可以在同一个链接上可以并发的发送不同的请求
  • Server Push
    • 在传统的HTTP协议中都是客户端主动,服务端被动
    • 而在HTTP2中,可以让服务端变被动为主动
    • 可以直接向客户端推送内容

程序示例

  • test.html
    <img src="/test.jpg" alt="">
    
  • server.js
    const http = require('http')
    const fs = require('fs')
    
    http.createServer(function (req, res) {
        console.log('request come', req.url)
    
        const html = fs.readFileSync('test.html', 'utf8');
        const img = fs.readFileSync('test.jpg');
        if (req.url === '/') {
            res.writeHead(200, {
                'Content-Type': 'text/html',
                'Connection': 'keep-alive',
                'Link': '</test.jpg>; as=image; rel=preload'
            })
            res.end(html);
        } else {
            res.writeHead(200, {
                'Content-Type': 'image/jpg',
                'Connection': 'keep-alive' // or close
            });
            res.end(img);
        }
    }).listen(8000, () => {
        console.log('server listening on 8000');
    })
    
  • 上述示例中'Link': '</test.jpg>; as=image; rel=preload'
    • Link头是HTTP2中指定推送内容的类型
    • 这里推送的是/test.jpg,注意这里是访问路径
    • as用于指定类型,此处是图片
    • rel=preload 表示进行一个服务端的预推送

配置Nginx

proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m;

server {
  listen       80;
  listen       [::]:80 default_server;
  server_name  test.com;

  return 302 https://$server_name$request_uri;

  location / {
    proxy_cache my_cache;
    proxy_pass http://127.0.0.1:8888;
    proxy_set_header Host $host;
  }
}

server {
  listen       443 http2;
  server_name  test.com;
  http2_push_preload  on;

  ssl on;
  ssl_certificate_key  ../certs/localhost-privkey.pem;
  ssl_certificate      ../certs/localhost-cert.pem;

  location / {
    proxy_cache my_cache;
    proxy_pass http://127.0.0.1:8888;
    proxy_set_header Host $host;
  }
}
  • 特别注意,针对我们的server_name,本机也要进行一些host的配置,此处不再赘述
  • 现在的HTTP2基于HTTPS, 虽然在HTTP2的协议定义中没有指定一定要使用HTTPS
  • 但是HTTP2是由谷歌开发的SPDY协议演化而来的, 而SPDY协议需要HTTPS
  • 所以目前HTTP2只能在HTTPS的基础上使用
  • 所以上述配置中 listen 443 http2 是规定的写法
  • http2_push_preload on; 是推送功能的开启

验证效果

  • 启动nginx和本地服务,访问我们的: https://test.com
  • 可以在Network中看到,Protocol已经变成了h2
  • 但是并没有看到是一个server push,而像是一个普通的请求
    • 其原因是,我们目前所配置的HTTPS是不安全的,谷歌浏览器拒绝接受服务端推送
    • 我们可以在 chrome://net-internnals/#http2 中看到网站使用了http2 push的功能
    • 显示Pushed有1条,Pushed and claimed有0条,意味着有1条推送,但并没有被浏览器接收
    • 浏览器在展示的时候把Pushed数据伪装成了普通请求的样子
  • 扩展:https://http2.akamai.com/demo/http2-lab.html
    • 可通过上面的网站来测试HTTP2的性能
    • HTTP2相较于HTTP1.1的性能有本质的提升,同时HTTP2开启了Server Push又提高了不少
    • 其整体性能提升不体现在Server Push上,而是体现在信道复用和分帧传输的设计上
    • 因为有了上述的设计,我们可以通过一个TCP链接进行并发就行了
  • 因为不是所有的浏览器都支持HTTP2,有时候我们需要回退到HTTP1.1
  • 如果使用Nginx来开启HTTP2, 它会帮我们进行一个兼容,这个兼容方案是:ALPN
    • 客户端和服务端进行协商到底使用哪个协议
    • 可以测试:$ curl -v https://test.com
      • 可以看到提示信息:ALPN, offering h2, ALPN, offering http/1.1
    • 我们直接使用 $ curl -v -k https://test.com
      • 可以看到提示信息:ALPN, server accepted to use h2
      • 这表示客户端如果支持h2, 服务端就会使用h2进行传输
    • 如果我们想使用http1.1访问: $ curl -v -k --http1.1 https://test.com
      • 可以看到ALPN, server accepted to use http/1.1
  • 我们在做开发的时候,直接使用HTTP1.1标准开发就行了,因为服务端一般不直接从客户端接收数据
  • Nginx可以帮我们做这些兼容,开发者无需考虑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wang's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值