###
1、前言
在web应用中,为了节省流量,降低传输数据大小,提高传输效率,常用的压缩方式一般都是gzip,今天我们来介绍另外一种更高效的压缩方式brotli。
Brotli 是基于LZ77算法的一个现代变体、霍夫曼编码和二阶上下文建模。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。
注意:使用算法的前提是启用了 https,因为 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。
2、浏览器对brotli协议的支持
3、图示各种压缩算法在不同level下的比较
下面图中可以看出brotli vs gzip 的压缩算法 总体来说brotli的总体性能更好,尤其是解压速度。我们在选择brotli算法或gzip时,需要根据实际场景进行调优
4、下载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
5、编译Brotli
nginx自1.9.11以后版本后支持动态模块,自此,给nginx添加模块再也不用重新编译nginx了,通过动态模块,你可以在运行时有有选择性的加载第三方或Nginx官方模块。新的实现方式通过API模块保持尽可能的向后兼容。
5.1下载解压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
5.2、编译动态模块
先进入解压后的nginx安装包目录,配置configure,然后用make modules。 cd nginx-1.14.2 ./configure --with-compat --add-dynamic-module=/usr/src/ngx_brotli # 配置编译参数常见报错 请见本文 第 11 章节 make modules 参数语法:--add-dynamic-module=[模块源码所在目录的绝对路径] 等运行完成后,查看编译好的模块 ls objs/*.so 输出: objs/ngx_http_brotli_filter_module.so objs/ngx_http_brotli_static_module.so
5.3、将编译好的模块文件复制到nginx动态模块加载目录
####################### nginx部署在物理机操作 mkdir -p /etc/nginx/modules cp objs/{ngx_http_brotli_filter_module.so,ngx_http_brotli_static_module.so} /etc/nginx/modules 其余物理机操作继续下一章节
####################### docker部署nginx开启brotli操作 [root@linux ~]# cp objs/{ngx_http_brotli_filter_module.so,ngx_http_brotli_static_module.so} /home/docker
[root@linux ~]# cat /home/docker/modules.conf load_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so;
[root@linux ~]# ls -l /home/docker/ total 148420 -rw-r--r-- 1 root root 469 Nov 3 13:22 Dockerfile -rw-r--r-- 1 root root 108 Nov 3 11:32 modules.conf
drwxr-xr-x 2 root root 78 Nov 3 17:38 nginx_ssl #【生成nginx https证书见https://www.cnblogs.com/faithH/p/15504753.html】 -rw-r--r-- 1 root root 947 Nov 3 16:33 nginx.conf #【此处nginx.conf文件配置详情,见本文第7章节】 -rwxr-xr-x 1 root root 4949608 Nov 2 20:31 ngx_http_brotli_filter_module.so -rwxr-xr-x 1 root root 66184 Nov 2 20:31 ngx_http_brotli_static_module.so
[root@linux ~]# ls -l /home/docker/nginx_ssl #【生成nginx https证书见https://www.cnblogs.com/faithH/p/15504753.html】
total 16
-rw-r--r-- 1 root root 1139 Nov 3 17:37 server.crt
-rw-r--r-- 1 root root 972 Nov 3 17:37 server.csr
-rw-r--r-- 1 root root 1679 Nov 3 17:37 server.key
-rw-r--r-- 1 root root 1139 Nov 3 17:38 server.pem
[root@linux ~]# cat /home/docker/Dockerfile FROM faith1/nginx:v1.17.10 COPY ngx_http_brotli_filter_module.so /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so COPY ngx_http_brotli_static_module.so /usr/lib/nginx/modules/ngx_http_brotli_static_module.so COPY modules.conf /etc/nginx/modules.conf COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
[root@linux ~]# cd /home/docker && docker build -t nginx-brotli:v1 .
[root@linux ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-brotli v1 3318bfeee264 18 hours ago 155MB
[root@test01 ~]# docker run -d --name nginx-brotli -p 80:80 -p 443:443 -v /home/docker/nginx.conf:/etc/nginx/nginx.conf -v /home/docker/nginx_ssl:/etc/nginx/nginx_ssl nginx-brotli:v1
# 至此docker nginx开启brotli全部完成
6、注册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 模块。 [root@linux ~]# cat /etc/nginx/modules.conf # Brotli模块 load_module modules/ngx_http_brotli_filter_module.so; load_module modules/ngx_http_brotli_static_module.so;
7、启用brotli压缩(全部配置)【必须在反向代理配置文件代码中添加:proxy_set_header Accept-Encoding "";】
Brotli和gzip是可以并存的,无需关闭gzip。
在/etc/nginx/nginx.conf开启Brotli:
[root@linux ~]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /etc/nginx/modules.conf;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##############################################
################################ 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;
##############################################
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
#server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/nginx_ssl/server.pem;
ssl_certificate_key /etc/nginx/nginx_ssl/server.key;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
proxy_set_header Accept-Encoding "";
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# server {
# listen 80;
# listen [::]:80;
# server_name _;
# root /usr/share/nginx/html;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /404.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
# Settings for a TLS enabled server.
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
# error_page 404 /404.html;
# location = /40x.html {
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
8、配置详解
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类型总是会被压缩。
9、重启nginx,使其配置生效
systemctl restart nginx
10、访问
11、附加:nginx配置编译参数常见报错
11.1、PCRE依赖包没有安装
报错信息: ./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the module by using --without-http_rewrite_moduleoption, or install the PCRE library into the system, or build the PCRE library statically from the source with nginx by using --with-pcre=<path> option.
解决办法:yum install pcre pcre-devel -y
11.2、OPENSSL依赖包没有安装
报错信息: ./configure: error: SSL modules require the OpenSSL library. You can either do not enable the modules, or install the OpenSSL library into the system, or build the OpenSSL library statically from the source with nginx by using --with-openssl=<path> option.
解决方法:yum install openssl openssl-devel -y
11.3、没有安装C语言
报错信息: checking for C compiler ... not found ./configure: error C compiler cc ... not found 解决方法:yum install gcc -y
本文参考原文:https://www.cnblogs.com/-wenli/p/13594882.html
###