Liaoct / blog

在这里记录一些个人经验与思考
22 stars 2 forks source link

HTT2学习 #16

Open ghost opened 5 years ago

ghost commented 5 years ago

HTT2学习

HTTP的现状

早年的解决办法

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命令,此处不再详细解释。