【Nginx24】Nginx学习:压缩模块Gzip

news2025/2/26 10:03:12

Nginx学习:压缩模块Gzip

又是一个非常常见的模块,Gzip 现在也是事实上的 Web 应用压缩标准了。随便打开一个网站,在请求的响应头中都会看到 Content-Encoding: gzip 这样的内容,这就表明当前这个请求的页面或资源使用了 Gzip 压缩。

具体的压缩算法咱们就不多说了,反正文字类的,相同字符越多的压缩效果越好。这也是大部分压缩算法的特点。其它的,咱们就直接看配置吧。

今天学习的内容都是可以设置在 http、server、location 中的,有特殊情况的我会单独说。

Gzip

Gzip 模块的全称是 ngx_http_gzip_module ,是包含在 Nginx 源码中的,不需要再独立的编译。它是一个使用 “gzip” 压缩算法压缩响应的过滤器,通常有助于将传输数据的大小减少一半甚至更多。需要注意的是,使用 SSL/TLS 协议时,压缩响应可能会受到 BREACH 攻击。我们先来看 Gzip 配置指令,然后下一小节再看一个综合测试。

gzip

启用或禁用响应的 Gzip 压缩功能。

gzip on | off;

默认是 off 的,在 nginx.conf.default 中是有它的注释的。一般来说,我们会在一个服务器上直接在 http 模块中配置全部的站点是否都开启 Gzip ,当然,也有可能会针对某个站点单独在对应的 server 中开启。而在 location 中,往往是让某些路径或文件资源不开启 Gzip 。这是为啥呢?

要知道,压缩是 CPU 密集型的操作,要耗费 CPU 资源的。特别是对于特别大的文件和特别高的压缩率。因此,图片和视频或者非常大的文件其实并不是很适合去进行 Gzip 压缩的,并且 Gzip 压缩还会加上自己的压缩头,反而会让这类文件变得更大,比如说 JPG 文件。这种文件本来就是通过图形压缩算法压缩过的,再上一道 Gzip 其实意义不大,而且很可能还会变得比原来更大。

因此,最合适压缩的,还是普通的文本类型的响应,比如纯文本文件、html/css/js响应、xml、JSON数据等等。

gzip_buffers

设置用于压缩响应的缓冲区的数量和大小。

gzip_buffers number size;

默认情况下,缓冲区大小等于一内存页。这是 4K 或 8K,具体取决于平台。

gzip_comp_level

设置响应的 gzip 压缩级别。

gzip_comp_level level;

默认值是 1 ,可接受的值在 1 到 9 的范围内。数值越大,压缩比率越高,文件越小,但 CPU 耗费资源也越高。小数值就是反过来的。通常来说,要么不配置用 1 ,要么 3、4、5 左右即可。

和压缩比率对应的还有一个变量 $gzip_ratio ,这个变量没法直接 return 出来,只能记录到日志中,大家可以复用之前 的那个 vvv 日志的配置,然后添加上这个变量,看看每个请求具体实现的压缩比是多少,计算为原始响应大小和压缩响应大小之间的比率。

gzip_disable

禁用对具有匹配任何指定正则表达式的“User-Agent”标头字段的请求的响应的 gzip 压缩。

gzip_disable regex ...;

特殊掩码“msie6” (0.7.12) 对应于正则表达式“MSIE [4-6].”,但运行速度更快。从 0.8.11 版开始,“MSIE 6.0; ... SV1”不包含在此掩码中。

其实就是针对指定的匹配到的 User-Agent 中的浏览器关键字段,不启用 Gzip 压缩。

gzip_http_version

设置压缩响应所需的请求的最低 HTTP 版本。

gzip_http_version 1.0 | 1.1;

默认值是 1.1 ,这个基本没啥人改了,现在 1.1 已经很普遍了。

gzip_min_length

设置将被压缩的响应的最小长度。

gzip_min_length length;

默认值是 20 ,就是不到这个长度的,就不压缩了。长度仅由 “Content-Length” 响应头字段确定。

gzip_proxied

根据请求和响应启用或禁用代理请求的响应 gzip 压缩。

gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;

默认值是 off ,请求被代理的结果是由“Via”请求头字段的存在决定的。该指令接受多个参数:

  • off 禁用所有代理请求的压缩,忽略其他参数

  • expired 如果响应标头包含带有禁用缓存值的“Expires”字段,则启用压缩

  • no-cache 如果响应头包含带有“no-cache”参数的“Cache-Control”字段,则启用压缩

  • no-store 如果响应头包含带有“no-store”参数的“Cache-Control”字段,则启用压缩

  • private 如果响应头包含带有“private”参数的“Cache-Control”字段,则启用压缩

  • no_last_modified 如果响应头不包含“Last-Modified”字段,则启用压缩

  • no_etag 如果响应头不包含“ETag”字段,则启用压缩

  • auth 如果请求标头包含“授权”字段,则启用压缩

  • any 为所有代理请求启用压缩

官方的解释是 仅将响应压缩到不会在代理服务器上缓存的请求是合理的 ,代理请求主要指的是一些高速缓存服务器或 CDN 网络,和 gzip_vary 指令类似。通过请求的 Via 请求头,判断当前的请求是不被代理转发过来的请求,如果有这个参数,那么 gzip_proxied 就会生效。

gzip_types

对除了 “text/html” 之外,还启用对指定 MIME 类型的响应的 gzip 压缩。

gzip_types text/html;

特殊值 “*” 匹配任何 MIME 类型 (0.8.29)。默认值 “text/html” 类型的响应总是被压缩的。

比如说,你想要压缩 JSON、XML 和 JPG 类型的资源,就可以这么配。

gzip_types application/json text/xml image/jpeg;

不用再加 text/html ,默认它就一直存在,写上了反而会报重复的错误。

gzip_vary

如果指令 gzip、gzip_static 或 gunzip 处于活动状态,则启用或禁用插入 “Vary: Accept-Encoding” 响应头字段。

gzip_vary on | off;

默认值是 off 的,Vary 是 HTTP 中响应头的一个标识,主要是和缓存代理服务器响应有关,针对现在比较流行的一些云服务,比如高速缓存中间件或者 CDN 网络。如果开启的话,就会添加一个上面那样的响应头,告诉缓存代理服务器缓存两种版本的资源:压缩和非压缩的,这有助于避免一些公共代理不能正确地检测 Content-Encoding 标头的问题。

假设有两个客户,一个使用的旧浏览器不支持压缩,一个使用新的浏览器支持压缩,如果他们都请求同一个网页,那么取决于谁先请求,压缩或非压缩版本便存储在CDN上。这样问题就出现了,旧浏览器请求常规网页但获得缓存的压缩版本,而新浏览器会获得缓存的非压缩版本但尝试去“解压”它。无论哪种方式都是坏消息。解决方法是,源服务器回送“Vary: Accept-Encoding”。如果你的网站使用了这些中间件或者 CDN ,记得开启它哦。

综合测试

先来一个整体的配置,我们直接到 http 下面去配置,这样的话所有的站点所有的目录都可以启用 Gzip 了,比较方便。

// http 下
  gzip on;
  gzip_comp_level 1;
  gzip_min_length 16;
  gzip_types text/plain image/jpeg;
  gzip_vary on;
  #gzip_disable ~ Chrome;
  #gzip_proxied any;

下面两个注释我们后面再说,先看看效果,配置上述内容之后,访问所有的页面都会在响应头中返回 Content-Encoding: gzip 这个内容,这就表示 Gzip 压缩已经启用了。那么是真的吗?咱们用 WireShark 抓包试试。

首先是关闭 Gzip 状态下抓到的数据。

ed989ea92e63c6b7841187141da0a0a6.png

可以看到,数据是以原文展示的,说明就是返回的普通文本字符串。现在咱们看看打开 Gzip 的效果。

7042f4cf94f9fbda460db9608c5d5b6f.png

好嘛,直接变乱码了,这就说明 Gzip 确实是启用了。如果文件内容不多,可能在浏览器返回的 Length 中看不到太大的差别,那么我们就可以自己写一个大点的页面,或者之前使用 php 循环输出多点内容。gzip_vary 开启后,响应头会有 Vary: Accept-Encoding 这样的内容返回回来, gzip_types 大家也可以自己测测,不添加那两个,直接访问 JPG 图片或者 txt 文档看看有没有压缩。这两个比较直观就不解释了,咱们主要看看别的。

压缩级别,这里我直接使用之前的那个循环打印10000 次 $_SERVER 的 PHP 文件来操作。另外,我们也可以调整一下 gzip_comp_level 的级别,一起看下效果。

79aaa6e7f7dc9d46f14f785a5ee3181d.png

怎么样,效果还是很明显的吧,返回的大小直接从 14.7M 变成了最小 74.1k 。因为我们的循环内容都是一样的,所以压缩比率非常高。查看等级 1 在日志中记录的 $gzip_ratio 达到了 67.31 ,而 9 的比例为 185.65 。

大小限制

在上面的配置中,我们设置了一个 gzip_min_length 16 ,表示小于 16 个字节的不会进行 Gzip 压缩,为啥是这个值呢?因为好测嘛,我们之前有个 a.txt 文件,里面的内容是 this is a.txt. 字符是 14 个,加上换行符正好 15 个字符。另外,记得还要配置 gzip_types ,把 text/plain 加上哦。

大家可以自己进行测试,直接访问 a.txt 是不会压缩的,修改 gzip_min_length 小于 16 之后,就会进行压缩了。

gzip_disable 与 gzip_proxied

在上面的配置中,gzip_disable 我配置的就是过滤掉 Chrome 浏览器,大家可以自己试试打开注释后,Chrome 浏览器访问还有没有 Gzip 。另一个的测试也不麻烦,可以使用 Postman ,添加一个请求头 Via ,值随便写,然后就会发现所有页面或资源的 Gzip 都失效了。现在打开注释,Gzip 又开始生效了。注意,gzip_proxied 判断的条件就是请求头有没有 Via ,至于 Via 的值是什么并不重要,咱们只是测试嘛。这个其实是针对于当前系统是否为被反向代理的,比如 CDN 的回源,当 CDN 回源到我们本地服务器时,或者其它 Nginx 反向代理到当前服务器时,就会加上,Via 请求头,正常情况下 Gzip 就不会对这些请求进行压缩处理了。gzip_proxied 就是用来控制这部分内容的,之前测试,如果在有 Via 请求头的情况下设置为 private ,则响应内容不包含 Cache-Control private,所有的 Gzip 都不生效,但是后期测好像又没用了,设置 gzip_proxied private; 就和设置成 any 的效果一样。好吧,不纠结了,这一块如果有了解的小伙伴欢迎留言指导。

GunZip

其实一般情况下,有上面 Gzip 模块的内容就够用了。但是 Nginx 还提供了两个和 Gzip 相关的拓展模块。这两个模块都需要额外安装,不是在 Nginx 源码中的。第一个就是 ngx_http_gunzip_module 模块,GunZip 的作用是使用“Content-Encoding: gzip”为不支持“gzip”编码方法的客户端解压缩响应。当需要存储压缩数据以节省空间和降低 I/O 成本时,该模块将很有用。

说人话,就是客户端如果不支持 Gzip 压缩,那么开启了这个模块功能之后,就还是会把 Gzip 的压缩内容反解压回去再响应给客户端。其实现在这个模块已经没啥用了,毕竟基本上所有的客户端或浏览器都是支持 Gzip 解压的。但是,不排除有特殊需求吧。它是通过添加 --with-http_gunzip_module 参数在 configure 时来进行编译安装的,只有两个配置项。

gunzip

为缺乏 gzip 支持的客户端启用或禁用 gzip 响应的解压缩。

gunzip on | off;

默认值是 off ,也就是关闭的。如果启用,则在确定客户端是否支持 gzip 时还会考虑以下指令:gzip_http_version、gzip_proxied 和 gzip_disable。要测试的话,其实可以使用 Postman ,将请求头中的 Accept-Encoding:gzip 去掉。这样,即使不动上面的那些配置,也就是保持 gzip 是开启的状态,返回的结果通过 WireShark 查看也是原文数据。大家可以测试一下哦。

gunzip_buffers

设置用于解压缩响应的缓冲区的数量和大小。

gunzip_buffers number size;

默认情况下,缓冲区大小等于一内存页。这是 4K 或 8K,具体取决于平台。

gzip_static

这个模块从名字上来看,好像是什么静态 Gzip 的意思,其实它是允许发送带有“.gz”文件扩展名的预压缩文件而不是常规文件。它的命名是 ngx_http_gzip_static_module 模块,也不是包含在 Nginx 核心源码中的,需要通过 --with-http_gzip_static_module 编译安装,只有一个配置项。

gzip_static on | off | always;

默认是 off ,启用(“on”)或禁用(“off”)检查预压缩文件的存在。还需要配合考虑了以下指令:gzip_http_version、gzip_proxied、gzip_disable 和 gzip_vary。

使用“always”值 (1.3.6),gzip 压缩文件在所有情况下都使用,而不检查客户端是否支持它。如果磁盘上没有未压缩的文件或者使用了 ngx_http_gunzip_module,这将很有用。

可以使用 gzip 命令或任何其他兼容的命令来压缩文件。建议原文件和压缩文件的修改日期和时间一致。

网上关于这个模块的资料很少,但通过上面官方文档中的描述,大概可以猜测到,就是我们可以在命令行通过 gzip 命令工具或者通过其它动态程序提前压缩好文件,和原始文件保持相同的名称,只是后缀名变成 .gz 的。然后尽量让它们的修改日期和时间一致。这样如果是开启 Gzip 的情况下,Nginx 就会直接发送 .gz 的这个预压缩文件,而不用自己再压缩一遍,能够有效减少压缩所带来的 CPU 消耗。

那么我们就拿 a.txt 来测试一下,首先使用 gzip 压缩一下,生成了一个 a.txt.gz 文件。

[root@localhost html]# gzip a.txt

不加任何参数的话,原来的 a.txt 直接就被打包成了 a.txt.gz 文件,原始文件也不存在了。然后编译安装 ngx_http_gzip_static_module 模块,之后也在 http 模块下设置 gzip_static on; 。直接访问 a.txt ,还是可以直接返回正常的文件响应。

接下来,我们再创建一个 a.txt 文件,让文件的内容与之前的文件略有不同。然后在请求的时候加上 Via 头,这样请求就不会走 gzip 了。这样就可以测试出在没有 Via 头的情况下,使用 gzip_static 确实直接就是使用 a.txt.gz 文件,而使用了 Via 就会看到原始的 a.txt 文件了。大家一定要自己测试一下哦。

总结

关于 Gzip 的内容相信大家还是比较好懂的,因为接触过这个的同学可能非常多。不管你是做网站开发还是写接口,减少带宽流量,优化加载速度,通过 Gzip 都是非常方便的。其实大家应该看出来了,大部分情况下,其实我们只需要配置 gzip 和 gzip_types 就可以了,有需要的话可以再配一下压缩比率 gzip_comp_level ,有这三个足以应付 9 成以上的业务需求了。

另外需要注意就是对于图片、流媒体这些,建议不要用,不过大家还是要自己试试,有的时候确实有效,有的时候真的会变得更大,这个东西吧,自己不试试是不知道的。另外顺便提一个静态资源的优化点,图片资源尽量使用 JPG ,因为它本身就是压缩类型的,同样的图片会比 PNG 或 GIF 要小。

参考文档:

http://nginx.org/en/docs/http/ngx_http_gzip_module.html

http://nginx.org/en/docs/http/ngx_http_gunzip_module.html

http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/990667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

grep wc 与 管道符

grep命令 可以通过grep命令,从文件中通过关键字过滤文件行。 语法: grep [-n] 关键字文件路径 选项-n,可选,表示在结果中显示匹配的行的行号。参数,关键字,必填,表示过滤的关键字,带有空格或其…

【已解决】uniapp使用vant-ui中的tab标签页的时候,发现底下红色的切换线不见了

问题截图 解决办法 按F12查看vant-ui源码你会发现他的Tab标签页里面有个width,但是我们引入到uniapp之后发现width没有了(不知道什么情况,可能是兼容问题吧) 所以我们解决的办法,只需要在App.vue中给全局.van-tabs__l…

Jmeter系列进阶-获取图片验证码(4)

安装工具 通过ocrserver工具识别图片验证码,解压后 .exe双击启动即可。 jmeter中使用 (1)HTTP请求获取验证码 (2)在获取验证码图片的接口下面添加监听器》保存响应到文件;如下图: &#x…

[Go 报错] go: go.mod file not found in current directory or any parent directory

Build Error: go build -o c:\Users\13283\Desktop\godemo\__debug_bin3410376605.exe -gcflags all-N -l . go: go.mod file not found in current directory or any parent directory; see go help modules (exit status 1) 原因分析: go 的环境配置问题。与 gol…

电脑磁盘分区形式是什么?如何更改?

磁盘分区形式介绍 在了解为什么以及如何更改分区形式之前,让我们对磁盘分区形式有一个基本的了解。一般来说,分区形式是指主引导记录(MBR)和 GUID 分区表(GPT)。 MBR和GPT是Windows系统中常用…

【HTTP爬虫ip实操】智能路由构建高效稳定爬虫系统

在当今信息时代,数据的价值越来越受到重视。对于许多企业和个人而言,网络爬取成为了获取大量有用数据的关键手段之一。然而,在面对反爬机制、封锁限制以及频繁变动的网站结构时,如何确保稳定地采集所需数据却是一个不容忽视且具挑…

3D视觉测量:3D空间圆拟合优化

文章目录 0. 测试效果1. 测量思路2. 部分调用代码文章目录:形位公差测量关键内容:通过视觉方法实现GD&T中的圆孔位置定位0. 测试效果 1. 测量思路 空间圆拟合是指在三维空间中找到最佳拟合圆的过程。这通常用于从一组三维点数据中找到一个圆,以最小化数据点到圆的距离之…

国标EHOME视频平台EasyCVR视频融合平台助力地下停车场安全

EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等,视频智能分析平台EasyCVR融合性强、开放度高、部署轻快,在智慧工地、智慧园区…

QT QFrame控件使用详解

本文详细的介绍了QFrame控件的各种操作,例如:设置框架形状、设置框架阴影、设置线宽、中间线宽、设置框架样式、设置大小策略、设置样式表、其它文章等等操作。 实际开发中,一个界面上可能包含十几个控件,手动调整它们的位置既费时…

YOLO目标检测——红火蚂蚁识别数据集+已标注yolo格式标签下载分享

实际项目应用:目标检测红火蚂蚁识别数据集在农业、生态学、环境保护、城市管理和学术研究等领域都有着广泛的应用。通过准确识别和定位红火蚂蚁,可以帮助我们更好地了解和管理这一入侵物种,从而减少其对环境和经济的负面影响。数据集说明&…

2023.9.7 关于 TCP / IP 的基本认知

目录 网络协议分层 TCP/IP 五层(四层)模型 应用层 传输层 网络层(互联网层) 数据链路层(网络接口层) 物理层 网络数据传输的基本流程 网络协议分层 为什么需要分层? 分层之后&#xff0c…

分布式锁怎么抗高并发 redis

比如,多个人下单某一个商品 怎么处理 分段加锁 合并扣减。 这里首先要让redis是集群,避开单机性能问题。 大概意思就是将商品分摊到多个服务器上,这样就减轻了单台的压力

智能小车之测速小车原理和开发

目录 1. 测速模块介绍 2. 测试原理和单位换算 3. 定时器和中断实现测速开发和调试代码 4. 小车速度显示在OLED屏 1. 测速模块介绍 用途:广泛用于电机转速检测,脉冲计数,位置限位等。有遮挡,输出高电平;无遮挡,输出…

解锁“文心一言”赋能大型连锁商超密码

解锁“文心一言”赋能大型连锁商超密码](https://mp.weixin.qq.com/s/rgj9sZFiajxc5EBVvnMH8Q) 2023年,“AIGC”江湖风起云涌,前有百度“文心一言”对标ChatGPT全民开放,后有其他公司的大模型迅速跟进落地,譬如某飞。 大模型这部…

第12篇:ESP32模拟SPI驱动12864LCD_ST7920显示屏

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 第4篇:vscodeplatformio搭建esp32 arduino开发环境 ​​​​​​第5篇:doit_esp32_devkit_v1使用pmw呼吸灯实验 第6篇:ESP32连接无源喇叭播…

什么是期权撮合成交?了解期权撮合成交规则。

在期权和期货市场中有着各种各样的交易方式,竞合竞价和撮合成交就是其中一种,它们都有自己独特的交易规则和交易时间,学习和理解他们对于投资者可以帮助投资者更好的选择挂单价位,最大程度的在合适价位达成成交。下文介绍什么是期…

C#__线程池的简单介绍和使用

/*线程池原理&#xff1a;&#xff08;有备无患的默认备用后台线程&#xff09;特点&#xff1a;线程提前建好在线程池;只能用于运行时间较短的线程。*/class Program{static void Main(string[] args){for (int i 0; i < 10; i){ThreadPool.QueueUserWorkItem(Download); …

源码剖析:Elasticsearch 段合并调度及优化手段

1、背景 经常看到集群的merge限流耗时比较高&#xff0c;所以想分析其原因、造成的影响、以及反思merge的一些优化手段。 比如下图中测试集群相关监控截图&#xff1a; 可是从磁盘的写入来看&#xff0c;并不高&#xff1a; 那么目前的情况带来哪些影响&#xff1f; 资源利用率…

Docker安装部署Nexus3作为内网镜像代理缓存容器镜像

Docker安装部署Nexus3作为内网镜像代理 一、背景描述 基础镜像比较小&#xff0c;仓库使用阿里云或者腾讯云拉取速度挺快&#xff0c;但是时光飞逝几年时间过去&#xff0c;再加上AI加持的情况下&#xff0c;有些镜像的大小已经接近20G&#xff01; 这种情况下不管是测试环境…

20230908-考题记录

题目描述 给定一个数组nums和窗口大小win&#xff0c;每个win种的最大值为maxNum,最小值为minNum&#xff0c;求出该数组所有窗maxNum和minNum的最大差值。 示例1&#xff1a; 输入&#xff1a; nums [2, 3, 5, 7, 6, 8, 1]; win 3 输出&#xff1a; 7 解析&#xff1…