阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx配置HTTP 2.0实践篇

201次阅读
没有评论

共计 5830 个字符,预计需要花费 15 分钟才能阅读完成。

科普时间

Nginx 配置支持 HTTP2.0,这是为了等以后有钱可以买个服务器的时候直接配置服务器体验一把网页 秒开 的快感,为啥配置 HTTP2.0 可以秒开网页?请静心往下看:

HTTP 2.0 带来了哪些新特性?

HTTP 2.0 带来了很多新的特性,这里不会一一详细介绍,只列举了几项,如有兴趣研究的童鞋请移步 官方 RFC 文档。

1.增加 二进制分帧

HTTP协议从 0.9 版本开始不断增加新的功能特性,但长远来看都是 向前兼容 的,HTTP 2.0 应用层 传输层 之间增加了一个 二进制分帧层,从而能够达到“在不改动 HTTP 的语义、HTTP 方法、状态码、URI 及首部字段的情况下,突破 HTTP 1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。”

Nginx 配置 HTTP 2.0 实践篇

如上图所示,在 二进制分帧层 上,HTTP 2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,其中 HTTP 1.1 的首部信息会被封装到 Headers 帧,而 request body 被封装到 Data 帧里面。

2. 压缩头部

如下图所示:HTTP 2.0客户端 服务端 使用 首部表 来跟踪和存储之间发送的 键 - 值 对,对相同请求而言不需要再次发送请求和相应发送,通信期间几乎不会改变的通用 键 - 值(如:用户代理、可接受的媒体类型)只需发送一次。

  • 如果请求不包含首部(如:对同一资源的轮询请求),那首部开销为零字节
  • 如果首部发生变化,那只需发送变化的数据在 Headers 帧里面,新增或修改的 首部帧 会被追加到 首部表

Nginx 配置 HTTP 2.0 实践篇

3. 多路复用

记得大学 计算机网络 计算机组成原理 这两门课都讲到了 多路复用 这个概念,当时一知半解(可能是老师讲得太抽象了 o(╯□╰)o)。相比一个入了门的前端开发在谈到 性能优化 的方法时都可以轻轻松松列举如下几点:

  • CSS 雪碧图合并 – 减少请求
  • 合并压缩 CSS 跟 JavaScript 代码 – 减少请求
  • CSS 代码放在 header 头部里面,JavaScript 代码放到 body 结束之前 – 因为 JavaScript 代码执行会阻塞

然后我们可以自豪地晒出下面的代码片段:

<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="xxx.cdn.com/??a.css,b.css" />
</head>
<body>
...
<script src="xxx.cdn.com/??a.js,b.js"></script>
</body>
</html>

HTTP 2.0多路复用 让我们回到了最原始最自然的写码状态,先看下图:

Nginx 配置 HTTP 2.0 实践篇

HTTP 1.1 而言,浏览器通常有链接的限制,即使开启多个链接,也需要付出相应的代码,而 多路复用 允许同时通过单一的 HTTP 2.0 连接发起多重的 请求 - 相应 消息。

这意味着 HTTP 2.0 的通信都在一个连接上完成了,这个连接可以承载任意数量的 双向数据流,直观来说,就是我们又可以开开心心写出下面代码:

<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="a.css" />
<link rel="stylesheet" href="b.css" />
</head>
<body>
...
<script src="a.js"></script>
<script src="b.js"></script>
</body>
</html>

 

4. 请求优先级

既然所有资源都可以并行交错发送,会不会导致下面这种情况呢?

浏览器:服务器,请给我需要的 CSS 文件
服务器:Biu,发送图片中…
浏览器:服务器,请给我需要的 JS 文件
服务器:Biu,发送图片中…
浏览器:服务器,你 TM 的倒是给我发送我需要的 CSS 文件跟 JS 文件呀!

这个时候 HTTP 2.0请求优先级 特性出场了,在每个 HTTP 2.0 里面有个 优先值 ,这个 优先值 确定着客户端跟服务器处理不同的 采取不同的 优先级策略 ,高优先级的应该优先发送,但这不会绝对的(绝对等待会导致 首队阻塞 问题)。在分配处理资源和客户端与服务器间的宽带,不同优先级的混合都是必须的。

5. 服务器提示

一般情况下,客户端需要请求啥东西告诉服务器,然后服务器返回对应资源回到客户端,这也是请求很慢的原因之一。HTTP 2.0 新增加 服务器提示,可以先于客户端检测到将要请求的资源,提前通知客户端,服务器不发送所有资源的实体,只发送资源的 URL。客户端接到提示后会进行验证缓存,如果发现需要这些资源,则正式发起请求。

这个技术跟我们常用的 预加载 技术实现差不多,但 服务器提示 是通过 HTTP Link HeaderLink Prefetching 语义重叠的部分来实现的。

Nginx 如何实现 HTTP 2.0 ?

打开 Nginx 官网 可以看到其中有一条新闻如下:

Nginx 配置 HTTP 2.0 实践篇

显然,Nginx 是已经有了一个 ngx_http_v2_module 模块用来支持 HTTP 2.0 的,但是还不是稳定版,所以想要尝鲜那就需要 手动升级 Nginx

科普时间到此结束,下面就让我们正式进入今天的主题:一步步实现 Nginx 配置 HTTP 2.0

Nginx 配置 HTTP 2.0 正式起航

下面内容有条件的同学请对比实践操作,体会更深。

我将从下面几步来介绍:

  • 准备工作
  • 源码安装升级 Nginx 到最新版(当前是 1.9.14)
  • 生成 SSL/TLS 安全证书
  • 修改 Nginx 配置

准备工作

在开始我们的任务之前,请先下载 OpenSSL,pcre,Zlib 跟 Nginx 源码,并且全部解压到同一个目录,假设为 nginx-build,这时候的代码结构如下:

nginx-build
nginx-1.9.14
pcre-8.38
openssl-1.0.2g
zlib-1.2.8

源码安装升级 Nginx 到最新版(当前是 1.9.14)

若之前用 brew 安装过 Nginx,请先执行 brew uninstall nginx 卸载。

准备工作做好之后���打开 Terminal 切换到上面的 nginx-build 目录,然后执行下面命令编译 Nginx:

# 先进入 nginx 源码目录
cd nginx-1.9.14

# 配置 Nginx 源码
# --prefix:配置 nginx 最终安装目录,可以修改为你想要的目录
# --with-http_ssl_module 跟 --with-http_v2_module 必带,因为 HTTP 2.0 采用 HTTPS,HTTPS 基于 SSL/TLS
sudo ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-pcre=../pcre-8.38 --with-openssl=../openssl-1.0.2g --with-zlib=../zlib-1.2.8 --with-http_v2_module
> 输入管理员密码然后回车

配置源码成功之后,为了避免 make 失败,因为我失败了(可能是人品不好…),反正我 make 的时候报了下面的错误:

Nginx 配置 HTTP 2.0 实践篇

所以建议大家跟我一样先修改一个配置文件,如下命令 (相对于nginx-build 目录):

cd nginx-1.9.14/objs
sudo vi Makefile
> 输入管理员密码然后回车
# 在 vi 模式下输入 '/',然后输入./config --prefix 定位到类似我下面的片段:
# && ./config --prefix=/Users/cainengtian/Downloads/software/nginx-1.8.0/../openssl-1.0.2d/.openssl no-shared \
# 将前面的 ./config 改为 ./Congigure darwin64-x86_64-cc,其他的不要改动,然后保存即可

接着回到 nginx-build 目录,然后执行下面命令编译:

cd nginx-1.9.14
sudo make && make install

如果没有报错那就编译成功,在终端试试 sudo nginx 启动,然后打开 http://localhost 能看到欢迎页,然后在终端输入 nginx -v 看到 nginx version: nginx/1.9.14

生成 SSL/TLS 安全证书

要配置 HTTP 2.0 就需要启动 HTTPS,那就需要生成一个 SSL/TLS 证书,而 OpenSSL 正好可以做这件事情,买不起证书但自己造一个来临时用还是可以的,直接执行下面命令:

# 切换到 nginx 的根目录(我这里是 /usr/local/nginx,请根据上一步编译时候指定的 --prefix对应修改)
cd /usr/local/nginx
cd conf

# 利用 openssl 命令生成公钥跟密钥
openssl genrsa -des3 -passout pass:x -out cert.pass.key 2048
openssl rsa -passin pass:x -in cert.pass.key -out cert.key
openssl req -new -key cert.key -out cert.csr
openssl x509 -req -days 365 -in cert.csr -signkey server.key -out cert.crt

# 将 crt 跟key 合并生成 pem 文件
cat server.crt server.key > server.pem

# 删除掉我们不需要用到的文件
rm -rf cert.crt cert.csr

修改 Nginx 配置

离成功之后一步之遥了,接下来就是最重要的一步,配置 Nginx 支持 HTTP 2.0,修改 Nginx 配置文件/usr/local/nginx/conf/nginx.conf

1. 将所有 HTTP 请求重定向到 HTTPS 请求

location / {
return 301 https://$host$remote_port$request_uri;
}

2. 配置 HTTPS server

server {
listen 443 ssl http2 default_server;
server_name localhost;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

# 我用原始的下面这段启动报错了,所以注释掉改用了后面那段
#ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers 'CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4;';
ssl_prefer_server_ciphers on;

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

可以注意到上面 HTTPS 的配置比之前多了一个 http2,这就是 ngx_http_v2_module 模块,若没有安装该模块启动一样会报错。

3. 重启服务器

配置完成之后,重新启动服务器即可:

sudo nginx -s reload

4. 预览

打开 http://localhost,自动跳转到 https://localhost,Done!

一点思考

虽然 HTTP 2.0 也已经不算是非常新的东西,要普及确实也需要很长一段时间,希望不久将来有钱买个服务器部署到自己网站上。

只有动手实践才知道看起来简单的东西实际上还是会碰到很多坑,anyway,一直在成长的路上~

下面关于 Nginx 的文章您也可能喜欢,不妨参考下:

CentOS 7.2 下编译安装 PHP7.0.10+MySQL5.7.14+Nginx1.10.1  http://www.linuxidc.com/Linux/2016-09/134804.htm

搭建基于 Linux6.3+Nginx1.2+PHP5+MySQL5.5 的 Web 服务器全过程 http://www.linuxidc.com/Linux/2013-09/89692.htm

Linux 下编译安装 Nginx 1.8.1 及配置 http://www.linuxidc.com/Linux/2017-02/140495.htm

CentOS 6.4 安装配置 Nginx+Pcre+php-fpm http://www.linuxidc.com/Linux/2013-08/88984.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

Nginx 的 500,502,504 错误解决方法 http://www.linuxidc.com/Linux/2015-03/115507.htm

Nginx 版本号修改隐藏及记录用户请求需要的时间  http://www.linuxidc.com/Linux/2017-02/141044.htm

CentOS 7 编译安装 Nginx1.10.2 脚本启动失败解决思路 http://www.linuxidc.com/Linux/2017-01/139794.htm

Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-02/141105.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计5830字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中