前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >省流量即省钱 - Nginx 开启支持谷歌Brotli压缩算法

省流量即省钱 - Nginx 开启支持谷歌Brotli压缩算法

原创
作者头像
缘、妙不可言
修改2019-09-09 21:11:57
3.1K3
修改2019-09-09 21:11:57
举报
文章被收录于专栏:深夜咖啡小屋深夜咖啡小屋

如果你不满足于gzip,请阅读本文;如果你没听过Brotli压缩。也请阅读本文

  • 什么是Brotli ?

Brotli最初发布于2015年,用于网络字体的离线压缩。Google软件工程师在2015年9月发布了包含通用无损数据压缩的Brotli增强版本,特别侧重于HTTP压缩。其中的编码器被部分改写以提高压缩比,编码器和解码器都提高了速度,流式API已被改进,增加更多压缩质量级别。新版本还展现了跨平台的性能改进,以及减少解码所需的内存。

与常见的通用压缩算法不同,Brotli使用一个预定义的120千字节字典。该字典包含超过13000个常用单词、短语和其他子字符串,这些来自一个文本和HTML文档的大型语料库。预定义的算法可以提升较小文件的压缩密度。

使用brotli取代deflate来对文本文件压缩通常可以增加20%的压缩密度,而压缩与解压缩速度则大致不变。使用Brotli进行流压缩的内容编码类型已被提议使用"br"

——(摘自维基百科)

Illustration of how the compression algorithm brotli works
Illustration of how the compression algorithm brotli works

Brotli压缩算法应用在HTTP请求

文字化描述该流程,如下:

  1. ??用户访问支持Brotli压缩的HTTP服务器上的网站或者Web应用
  2. 浏览器通过使用Accept-Encoding标头通知HTTP服务器它支持解压缩的内容类型
  3. HTTP服务器根据请求中包含的压缩算法决定要哪种压缩内容
  4. 服务器通过返回头部Content-Encoding向浏览器端表明数据的压缩方式
  5. 浏览器将数据解压并展示在页面上

浏览器支持情况

  • Mozilla Firefox >= 44
  • Google Chrome > 49
  • Opera >= 38
  • 如何使Nginx支持Brotli?

截止至目前nginx的最新版本(主线1.15.1或1.14.0稳定版),nginx源码中并不支持br压缩,所幸谷歌为我们提供了第三方模块来支持br压缩,所以只需在编译nginx时加上ngx_brotli这个模块,即可支持BR

以Centos7+nginx 1.14.0,我分享下编译过程及注意事项

1. 从nginx官网上获取nginx源码并解压备用

代码语言:javascript
复制
curl http://nginx.org/download/nginx-1.14.0.tar.gz | tar -xzv -C /usr/src/

2. 从github上拉取ngx_brotli源码,这里我同样把源码放在/usr/src目录下

代码语言:javascript
复制
cd /usr/src
git clone https://github.com/google/ngx_brotli
cd ngx_brotli && git submodule update --init 

3. (trick)通常服务器上用的nginx都是有一大堆编译参数的,为了最快的获得这些参数并在此基础上增加第三方模块,可以安装由nginx编译好的rpm包或deb包来完成nginx初始配置。

代码语言:javascript
复制
vim /etc/yum.repos.d/nginx.repo

复制填入以下内容,:wq保存退出。

代码语言:javascript
复制
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

接下来就是yum安装一大堆,包括nginx、nginx的依赖、编译环境工具

代码语言:javascript
复制
yum install nginx gcc make openssl-devel

4. 现在来开始编译,首先从已有的nginx中获取编译参数

代码语言:javascript
复制
nginx -V

复制 "configure arguments:"后面的参数,在末尾加上--add-dynamic-module=/usr/src/ngx_brotli

注意:/usr/src/ngx_brotli应与第2步中的代码存放路径保存一致;用的是--add-dynamic-module而不是--add-module是为了编译好的模块能复用(Nginx 1.9.11及以后支持动态加载模块)

代码语言:javascript
复制
cd /usr/src/nginx-1.14.0 && ./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' \
--add-dynamic-module=/usr/src/ngx_brotli

看到出现下列信息,说明模块源码已被正确识别

代码语言:javascript
复制
configuring additional dynamic modules
adding module in /usr/src/ngx_brotli
 + ngx_brotli was configured

接下来就是正式编译及安装了

代码语言:javascript
复制
make -j4 && make install

至此安装完成。

5. 最后一步,修改配置文件开启BR压缩

代码语言:javascript
复制
vim /etc/nginx/conf.d/enable_brotli.conf

内容大致如下:

代码语言:javascript
复制
brotli on;
brotli_comp_level 5; 
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;

brotli Brotli压缩开关,默认off

brotli_comp_level 控制br压缩率,范围0~11,默认6,数字越高压缩效果越好,但更耗时耗CPU资源

brotli_types 对哪些类型的HTTP返回进行压缩

更多设置项请参考官方github

常见问题FAQ:

  • 问:nginx -t 时提示错误
代码语言:javascript
复制
nginx: [emerg] unknown directive "brotli" in /etc/nginx/conf.d/enable_brotli.conf:1

答: 这是因为nginx没加载到brotli模块,所以识别不了对应的配置项,需在主配置文件中/etc/nginx/nginx.conf加载模块支持brotli(版本>=1.9.11 & modules文件夹下存在该模块,若低于1.9.11,只能重新编译nginx支持了)

代码语言:javascript
复制
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
#就是下面这一句,注意上下文位置
load_module "modules/ngx_http_brotli_filter_module.so";
http {
      ...
}
  • 问:为啥正确配置了br压缩,nginx也正常启动,然而浏览器端控制台查看请求却没有生效呢?

答:①检查浏览器支持状况(点我),并不是所以浏览器都支持

②检查你的网站是否为HTTPS,目前br压缩只支持HTTPS请求(国外有篇文章谈到过)

  • 问:brotli_static 配置项的如何使用及使用场景?

答:前端项目在打包发布的时候(使用webpack等工具),将某些类型的静态文件生成对应的压缩文件,例如:由vendor_d0cfe49e718c1366c661.js 压缩生成 vendor_d0cfe49e718c1366c661.js.br

nginx检测到对应请求的br压缩文件存在(brotli_static需为on)时,会将事先压缩的.br文件返回到浏览器端以省去了压缩步骤,从而节省CPU资源。如果事先以最高压缩比压缩,那么还能进一步节省流量。相关工具有brotli-webpack-plugin (webpack插件)、brotli(谷歌提供,包含常见语言的压缩实现)

参考文章:

Brotli and Static Compression

What is Brotli?

把Gzip换成Brotli的Nginx配置教程

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ——(摘自维基百科)
  • 浏览器支持情况
  • 常见问题FAQ:
  • 参考文章:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com