Nginx开启Brotli压缩算法实现过程详解


Posted in Servers onMarch 31, 2021

前言

在web应用中,为了节省流量,降低传输数据大小,提高传输效率,常用的压缩方式一般都是gzip,今天我们来介绍另外一种更高效的压缩方式brotli。

Brotli 是基于LZ77算法的一个现代变体、霍夫曼编码和二阶上下文建模。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。

注意:使用算法的前提是启用了 https,因为 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。
关于Brotli 算法详细请查看:https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Brotli

浏览器对brotli协议的支持

Nginx开启Brotli压缩算法实现过程详解

各种压缩算法的在不同level下的比较

Nginx开启Brotli压缩算法实现过程详解

从图中可以看出brotli vs gzip 的压缩算法 总体来说brotli的总体性能更好,尤其是解压速度。我们在选择brotli算法或gzip时,需要根据实际场景进行调优

下载Brotli

google/ngx_brotli 从 16年12月的版本起,开始内置google/brotli,所以我们不需要额外编译bagder/libbrotli库,让安装变得简单起来。 我们将google/ngx_brotli下载并解压到/usr/src/ngx_brotli目录

cd /usr/src

git clone https://github.com/google/ngx_brotli.git

然后在下载google/brotli并解压到/usr/src/ngx_brotli/deps/brotli

cd /usr/src/ngx_brotli/deps && rm -rf brotli
git clone git@github.com:google/brotli.git
cd /usr/src/ngx_brotli && git submodule update --init

编译Brotli

nginx自1.9.11以后版本后支持动态模块,自此,给nginx添加模块再也不用重新编译nginx了,通过动态模块,你可以在运行时有有选择性的加载第三方或Nginx官方模块。新的实现方式通过API模块保持尽可能的向后兼容。

下载解压nginx安装包

请下载与当前nginx版本相同的nginx安装包。nginx官方下载地址:http://nginx.org/en/download.html。 这里假设当前服务器nginx是1.14.2版本。

可通过命令,获取当前nginx版本

nginx -v

输出

nginx version: nginx/1.14.2

下载nginx安装包

cd /usr/src
wget http://59.80.44.46/nginx.org/download/nginx-1.14.2.tar.gz

解压安装包

tar -xvf nginx-1.14.2.tar.gz

编译动态模块

先进入解压后的nginx安装包目录,配置configure,然后用make modules。

cd nginx-1.14.2
./configure --with-compat --add-dynamic-module=/usr/src/ngx_brotli
make modules

参数语法:--add-dynamic-module=[模块源码所在目录的绝对路径]

等运行完成后,查看编译好的模块

ls objs/*.so

输出:

objs/ngx_http_brotli_filter_module.so objs/ngx_http_brotli_static_module.so

将编译好的模块文件复制到nginx动态模块加载目录

cp objs/{ngx_http_brotli_filter_module.so,ngx_http_brotli_static_module.so} /etc/nginx/modules

注册Brotli模块

为了方便管理nginx动态模块,建议新建一个modules.conf文件,单独管理动态模块。

touch /etc/nginx/modules.conf

在/etc/nginx/nginx.conf配置文件里引入modules.conf文件,找到以下内容并修改:

pid /var/run/nginx.pid;

include /etc/nginx/modules.conf;

打开/etc/nginx/modules.conf,注册刚才编译好的 Brotli 模块。

# Brotli模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

启用Brotli压缩

Brotli和gzip是可以并存的,无需关闭gzip。

在/etc/nginx/nginx.conf开启Brotli:

http {
  ...
  # gzip
  gzip on;
  gzip_min_length 1k;
  gzip_buffers 4 32k;
  gzip_http_version 1.1;
  gzip_comp_level 5;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
  gzip_vary on;
  gzip_proxied any;
  gzip_disable "MSIE [1-6]\.";

  # brotli
  brotli on;
  brotli_comp_level 6;
  brotli_buffers 16 8k;
  brotli_min_length 20;
  brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
  ...
}

gzip与brotli的配置详情

gzip调优
使用gzip压缩功能,可能为我们节约带宽,加快传输速度,有更好的体验,也为我们节约成本,所以说这是一个重点。 关于gzip详细介绍可点击这里;

gzip on 开启gzip压缩功能。

gzip_min_length 1k

设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是 0 ,不管页面多大都进行压缩,建议设置成大于 1K ,如果小与1K可能会越压越大。

gzip_buffers

压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。

gzip_http_version 1.1

压缩版本,用于设置识别HTTP协议版本,默认是 1.1 ,目前大部分浏览器已经支持GZIP解压,使用默认即可。

gzip_comp_level 5

压缩比例,用来指定gzip压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。推荐设置为 5 。

gzip_types

用来指定压缩的类型,text/html类型总是会被压缩。

gzip_vary on

和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩。

gzip_proxied any

nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含Via的header头。默认是 off 。 可选参数值:

  • off 关闭所有的代理结果数据的压缩
  • expired 启用压缩,如果header头中包含 Expires 头信息
  • no-cache 启用压缩,如果header头中包含 Cache-Control:no-cache 头信息
  • no-store 启用压缩,如果header头中包含 Cache-Control:no-store 头信息
  • private 启用压缩,如果header头中包含 Cache-Control:private 头信息
  • no_last_modified 启用压缩,如果header头中不包含 Last-Modified 头信息
  • no_etag 启用压缩 ,如果header头中不包含 ETag 头信息
  • auth 启用压缩 , 如果header头中包含 Authorization 头信息
  • any 无条件启用压缩

gzip_disable

禁用IE6的gzip压缩。 IE6对gzip的压缩支持很不好,会造成页面的假死。为了避免IE6出现问题,建议加上这个参数。

brotli调优

Google 认为互联网用户的时间是宝贵的,他们的时间不应该消耗在漫长的网页加载中,因此在 2015 年 9 月 Google 推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压塑压缩效率。 关于brotli详细介绍可点击这里;

注:如果未安装brotli模块,此部分配置项无需配置,可略过。

brotli on

开启brotli压缩功能。

brotli_comp_level 6

压缩比例,用来指定brotli压缩比,1 压缩比最小,处理速度最快,11 压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。默认值为 6 ,使用默认值即可。

brotli_buffers 16 8k

设置用于压缩响应的缓冲区number和size。默认情况下,缓冲区大小等于一个内存页面。 默认值:32 4k|16 8k。

brotli_min_length 20

设置length要压缩的响应的最小值,长度仅由Content-Length响应头字段确定。默认为 20 。

brotli_types

用来指定压缩的类型,text/html类型总是会被压缩。

gzip与brotli的配置详情在反向代理配置文件代码中添加:

proxy_set_header Accept-Encoding "";

范例:

server {
  ...
  location / {
    ...
    proxy_set_header Accept-Encoding "";
    ...
  }
  ...
}

重启nginx,使其配置生效

systemctl restart nginx

Brotli 压缩只能在https中生效,因为 在 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。
清理临时文件

要养成好习惯,每次编译完后都要把应用包解压出来的文件或目录进行删除。

rm -rf /usr/src/{nginx-1.14.2/,ngx_brotli/}

最后检查是否生效

打开网页,用chrome开发者工具调试,在Network一栏会发现有content-encoding:br,同时网络耗时也会明显减少。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Servers 相关文章推荐
nginx处理http请求实现过程解析
Mar 31 Servers
apache基于端口创建虚拟主机的示例
Apr 24 Servers
Nginx中使用Lua脚本与图片的缩略图处理的实现
Mar 18 Servers
微信告警的zabbix监控系统 监控整个NGINX集群
Apr 18 Servers
Windows Server 2012配置DNS服务器的方法
Apr 29 Servers
nginx配置限速限流基于内置模块
May 02 Servers
讨论nginx location 顺序问题
May 30 Servers
使用Apache Camel表达REST服务的方法
Jun 10 Servers
windows server2012 R2下安装PaddleOCR服务的的详细步骤
Sep 23 Servers
CentOS7设置ssh服务以及端口修改方式
Dec 24 Servers
ubuntu20.04虚拟机无法上网的问题及解决
Dec 24 Servers
码云(gitee)通过git自动同步到阿里云服务器
Dec 24 Servers
Nginx配置SSL证书出错解决方案
Mar 31 #Servers
Nginx配置并兼容HTTP实现代码解析
Mar 31 #Servers
基于Nginx实现限制某IP短时间访问次数
Mar 31 #Servers
Nginx tp3.2.3 404问题解决方案
Mar 31 #Servers
解决Nginx 配置 proxy_pass 后 返回404问题
nginx配置ssl实现https的方法示例
Mar 31 #Servers
Nginx解决前端访问资源跨域问题的方法详解
Mar 31 #Servers
You might like
php做下载文件的实现代码及文件名中乱码解决方法
2011/02/03 PHP
PHP中is_file不能替代file_exists的理由
2014/03/04 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
记Laravel调用Gin接口调用formData上传文件的实现方法
2019/12/12 PHP
javascript静态的url如何传递
2007/05/03 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
javascript实现不同颜色Tab标签切换效果
2016/04/27 Javascript
深入理解js promise chain
2016/05/05 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
前端 Vue.js 和 MVVM 详细介绍
2016/12/29 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
详解nodejs微信公众号开发——1.接入微信公众号
2017/04/10 NodeJs
BootStrap 表单控件之单选按钮水平排列
2017/05/23 Javascript
vue中页面跳转拦截器的实现方法
2017/08/23 Javascript
Vue父子之间值传递的实例教程
2020/07/02 Javascript
手把手教你实现 Promise的使用方法
2020/09/02 Javascript
[51:36]EG vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.24
2018/08/25 DOTA
[02:28]PWL开团时刻DAY3——Ink Ice与DeMonsTer之间的勾心斗角
2020/11/03 DOTA
写了个监控nginx进程的Python脚本
2012/05/10 Python
Python对象体系深入分析
2014/10/28 Python
在Python中使用HTML模版的教程
2015/04/29 Python
python中正则的使用指南
2016/12/04 Python
python之Character string(实例讲解)
2017/09/25 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
2018/05/30 Python
python内置数据类型之列表操作
2018/11/12 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
pytorch实现查看当前学习率
2020/06/24 Python
美国在线轮胎零售商:SimpleTire
2019/04/08 全球购物
一些Unix笔试题和面试题
2012/09/25 面试题
创业大赛策划书
2014/03/01 职场文书
科长竞聘演讲稿
2014/05/16 职场文书
党的群众路线教育实践活动调研报告
2014/11/03 职场文书
SpringAop日志找不到方法的处理
2021/06/21 Java/Android
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS