Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTT2学习 #16

Open
ghost opened this issue Apr 8, 2019 · 0 comments
Open

HTT2学习 #16

ghost opened this issue Apr 8, 2019 · 0 comments

Comments

@ghost
Copy link

ghost commented Apr 8, 2019

HTT2学习

HTTP的现状

  • HTTP 1.1过于庞大,包含太多可选项,导致学习与实现都非常困难。许多实用功能被边缘化,已实现功能却很少被使用。
  • 未能充分利用TCP的性能。随着传输大小和资源量的增加,加载速度成为瓶颈。
  • HTTP 1.1对网络延迟敏感。
  • HTTP pipelining的线头阻塞问题(Head-of-line block)。同一个TCP连接上的http请求,必须按顺序返回,耗时的请求会阻塞后面的返回。

早年的解决办法

  • 雪碧图(可能会缓存很多用不到的资源;不能选择保留其中几个小图)
  • 内联图片(代码体积增加,无法针对静态资源单独部署与加速,比如CDN)
  • 合并代码(减少HTTP链接数)
  • 域名分片(避开浏览器对同一域名TCP链接上限的限制)

HTTP/2的几个理念

二进制协议

HTTP 1.1是基于文本的协议,但HTTP/2是一个二进制协议。

优点:

  • 移除了文本协议中的空白符及其他冗余,对帧的起始和结束识别变得更加容易。
  • 分离协议本身的内容,结构更加清晰。
  • 压缩头部

二进制帧格式

公共字段:Type, Length, Flags, Stream Identifier和frame payload

另外还有10种不同的帧,例如对应于HTTP 1.1的DATA和HEADERS基础帧。

多路复用

每个HTTP2链接可以包含多个并发的二进制流。每个流中,又包含着来自客户端与服务端的二进制帧,Stream Identifier则关联到一个“流”。

流既可以被客户端/服务器端单方面的建立和使用,也可以被双方共享,或者被任意一边关闭。

同一个HTTP2连接,可以进行多个流的消息帧传送,消息帧被交错的混合在一起,接收方会将各个流中的数据进行整合,拼接成完整的消息。这便是多路复用。

理解:每个request/response都是一个流,每个流都由多个二进制帧组成,在HTTP2连接上,消息只会以二进制帧的形式进行传递,流是一个抽象概念。同一时间可以将多个消息流的帧进行投递。

优先级和依赖性

流具有优先级和依赖性,PRIORITY帧可以用来表示依赖关系。

头部压缩

HTTP 1.x每次请求都需要带着(基本)相同的头部信息,以及cookies信息,这让每个请求看起来都大致相同。这部分相同的内容,在HTTP/2会被压缩。

中断请求

在http2里面,我们可以通过发送RST_STREAM帧来实现中断请求,从而避免浪费带宽和中断已有的连接(主要是TCP链接)。

服务端推送

服务端现在可以主动先客户端推送消息了。但是需要客户端显示的允许推送功能,可以通过发送一个RST_STREAM帧来中止。

流量控制

暂时不知道怎么用。

备选服务

发送Alt-Svc头通知客户端向新的服务器建立连接。一般用在负载均衡。

Nginx开启HTTP 2服务

此处使用最新版的nginx-1.14.0(windows)做示例演示。

查看是否支持http 2:

nginx -V

从结果可知nginx-1.14.0(windows)已经默认包含--with-http_v2_module

修改配置文件:

server {
       listen       443 ssl;
       server_name  localhost;

       ssl_certificate      dmail.cert;
       ssl_certificate_key  dmail.key;

       ssl_session_cache    shared:SSL:1m;
       ssl_session_timeout  5m;

       ssl_ciphers  HIGH:!aNULL:!MD5;
       ssl_prefer_server_ciphers  on;

       location / {
           root   www;
           index  index.html index.htm;
       }
    }

这里需要自己添加证书文件dmail.certdmail.key

为了对比HTTP 2服务是否真实的启用,此处先不打开HTTP 2功能。

添加www目录及文件:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>http2</title>
    <link href="style.css" rel="stylesheet">
</head>

<body>
    <div class="app">
        <img src="image.jpg" />
        <p>
            Welcome HTTP 2.0
        </p>
    </div>
</body>
</html>

style.css

img {
    width: 300px;
    height: 200px;
}
.app {
    text-align: center;
}

以及一张图片image.jpg

启动Nginx,在浏览器查看结果。

http1

从协议栏可知当前是HTTP 1.1版本。

修改nginx.conf:

listen       443 ssl http2;

重启服务,查看结果。

http2

协议栏已经变成h2,HTTP/2服务启动成功。

另外,在地址栏输入如下命令:

chrome://net-internals/#http2

也可以查看HTTP/2服务。

服务端推送

目前为止,index.html完整显示发起了上次http请求,分别请求index.html本身、style.cssimage.jpg

现在我们让服务器,主动推送style.cssimage.jpg

修改配置:

location / {
   root   www;
   index  index.html index.htm;
   http2_push /style.css;
   http2_push /image.jpg;
}

重启服务,然后查看结果。

http-push

服务端推送成功。

服务端推送除了使用http2_push指令,还可以在代码中指定响应头的Link命令,此处不再详细解释。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants