返回顶部
首页 > 资讯 > 服务器 >一篇文章读懂nginx的gzip功能
  • 217
分享到

一篇文章读懂nginx的gzip功能

2024-04-02 19:04:59 217人浏览 泡泡鱼
摘要

目录前言语义:拓扑:仿真:验证:gzip_proxied的参数解析:小结:总结前言 Http中包体【body】压缩协商对应的头字段为Accept-Encoding/Content-E

前言

Http中包体【body】压缩协商对应的头字段为Accept-Encoding/Content-Encoding。对于HTTP包体压缩,Nginx的ngx_http_gzip_module模块提供了动态gzip压缩功能,并且有很精细的控制。

包括:

  • 开启关闭gzip压缩: gzip on|off
  • 对指定类型的文件进行压缩: gzip_types
  • 文件最小压缩阈值: gzip_min_length
  • 设置压缩率: gzip_comp_level
  • 查看压缩率: $gzip_ratio
  • 是否插入Vary: Accept-Encoding头字段: gzip_vary
  • 禁止指定浏览器使用压缩:gzip_disable
  • 是否对代理请求响应压缩:gzip_proxied

关于Nginx gzip基本功能,其语义,逻辑,配置和使用都相当简单,网上相关文章也很多,本文不再赘述,具体细节可以参看下文的配置实例及说明。本文将重点讨论其中的gzip_proxied指令的语义和使用,其涉及若干个参数,特定的应用场景,最为复杂,且网上文章涉及不多。

语义:

gzip_proxied的基本逻辑是对于代理请求,根据请求及回应的头字段决定是否压缩响应包体。判断的依据是请求头中是否携带Via头字段。

如:

拓扑:

对应的典型网络拓扑如下:

client — proxy1 — proxy2 — … proxyn — reverse proxy — origin WEB

我们的配置点在reverse proxy上, 也就是企业提供对外WEB服务的边缘的反向代理服务器。通常,proxyx会通过Via头字段标记消息自己的版本号和名称,从而形成了一条有序的消息路径,方便排错。

这是一个取自京东首页的Via字段的值,表示博主访问京东首页中间经过了2台代理服务器。

Via: http/1.1 ORI-CLOUD-HEN-MIX-109 (jcs [CSSSfU]), http/1.1 HENzhengzhou-CT-1-MIX-34 (jcs [cRs f ])

仿真:

我们可以通过在curl中添加头字段Via,模拟该场景。

curl -H 'Via: 1.1 aaa' test/200_accept_encoding.css --compressed -I

验证:

响应包体是否压缩,可以curl -I查看响应头中是否有Content-Encoding: gzip

如:

HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Fri, 18 Feb 2022 03:25:26 GMT
Content-Type: text/css
Last-Modified: Tue, 08 Feb 2022 15:48:26 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"620290ca-3523"
Content-Encoding: gzip

压缩率可以查看log

tail -f ../logs/200_accept_encoding_access.log

47151 192.168.31.133 - - [18/Feb/2022:10:08:07 +0800] "GET /200_accept_encoding.css HTTP/1.1" 200 2646 "-" "curl/7.61.1" "-" 5.16

其中5.16就是压缩率

本文使用的是nginx 1.20.1, 客户端工具是curl 7.61.1, 测试文件为200_accept_encoding.css,可自行选择任意文件测试。

[root@test01 conf]# nginx -v
nginx version: nginx/1.20.1

[root@test01 conf]# curl -V
curl 7.61.1 (x86_64-redhat-linux-gnu) libcurl/7.61.1 OpenSSL/1.1.1k zlib/1.2.11 brotli/1.0.6 libidn2/2.2.0 libpsl/0.20.2 (+libidn2/2.2.0) libssh/0.9.4/openssl/zlib nghttp2/1.33.0

gzip_proxied的参数解析:

  • off gzip_proxied的缺省参数是off,语义是不对代理请求的回应进行压缩。
  • any 对任意代理请求回应压缩,语义正好和off相反。
  • expired 如果回应中包含头字段Expires,并且其值响应导致不会缓存,则压缩。因此可以构造缓存不过期,缓存过期2种场景,分别验证。回应中添加Expires头字段可以用expires指令。
#expires 1h; #缓存有效期1小时 --->不压缩
#expires epoch;#缓存有效期设为1970年1月1日0时,即必然过期,不缓存 --->压缩
  • no-cache no-store private 此3个参数有类似的行为和语义,放在一起说,语义是如果响应头字段包含Cache-Control: xxx,xxx是上述参数中的一个,则压缩。

注:响应中需要显示地携带Cache-Control头字段,如果不包含则压缩。

#gzip_proxied no-cache;
#gzip_proxied no-store;
#gzip_proxied private;

响应中添加Cache-Control头字段用add_header指令

#add_header Cache-Control no-store;
#add_header Cache-Control no-cache;
#add_header Cache-Control private;

可以同时设置多个gzip_proxied条件:

#gzip_proxied no-cache no-store private;

add_header也可以为Cache-Control设置多个值,对于这种有冲突的Cache-Control设置,以最严格的限制为准,如本例是no-store生效。

#add_header Cache-Control no-store,no-cache,private;
  • no_etag 语义是如果回应中不包含头字段ETag,则压缩。

ETag默认打开,用etag off可以关闭。

#etag off;
  • no_last_modified 语义是如果回应中不包含头字段Last_modified,则压缩。

#未找到关闭last_modified的方法,abort。

  • auth 语义是请求中包含Authorization时压缩

配置下面2条指令可以仿真基本网页认证:

#auth_basic "test for auth_basic";
#auth_basic_user_file ../src/usr;

小结:

  1. gzip_min_length的优先级高于gzip_proxied,如果由于gzip_min_length的设置导致不压缩,则gzip_proxied即使满足压缩条件也不会压缩。
  2. 上述gzip_proxied的参数,除auth是看请求头字段,其它都是看响应头字段。
  3. off, any是一对互斥参数,表达了对代理请求是全部不压缩,或全部压缩两种相反的语义。
  4. no-cache,no-restore,priviate,no_etag,no_last_modified,都和缓存相关,表达的语义可以归纳为如果响应不缓存,则压缩,其区别只在于判断的条件的差异,当然,也可以一次性都设置上。那么为何响应不缓存就压缩呢?官方文档没有描述,博主推测和使用场景有关。
    a. 不缓存意味着不会在代理服务器上保留响应副本,那么应该尽早在消息源头压缩,减少链路上的带宽消耗。
    b. gzip是CPU密集型的使用,如果响应缓存,则可以选择在下游代理服务器上启用压缩,从而分担上游服务器的压力。

下面是具体的配置,实践实践再实践才是理解和领会相关指令和参数最有效的方法。

配置文件:

log_fORMat  gzip  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" $gzip_ratio';
server {
		listen 80;
        server_name  test test1;
		
		root html;


        access_log  logs/200_accept_encoding_access.log gzip;
		error_log logs/200_accept_encoding_error.log debug;

		default_type text/plain;
		
		#gzip off;#这是设置为off,原因是我在http级别已经把gzip打开了。
		gzip_buffers 16 8k;# gzip_buffers number size;
		gzip_comp_level 6;#设置压缩级别,缺省为1,可以不用改,级别6大约和gzip命令行缺省压缩率相当。
		#gzip_disable "(Chrome|curl|Firefox)";#根据User-Agent的返回值,针对特定客户端禁止压缩。这里把3种客户端都禁了。
		#Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
		#curl/7.61.1
		#Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
		#gzip_http_version 1.1;#指定gzip压缩针对的HTTP版本
		#gzip_min_length 13603;#设定最小待压缩的文件大小,大小的依据是Content-Length,使用的测试文件为200_accept_encoding.css
		gzip_min_length 620;#index.html文件大小正好是620
		#gzip *可以表示所有文件类型
		gzip_types application/javascript application/x-javascript text/css *;
		#mp4有专属的mime类型,video/mp4,而不是application/octet-stream,可以在conf/mime.types中查看详细的mime类型。
		#gzip_types application/javascript application/x-javascript text/css application/octet-stream;
		#gzip_types application/javascript application/x-javascript text/css video/mp4;

		gzip_vary on;#控制是否插入Vary: Accept-Encoding头字段。

		#gzip_proxied off;#设置是否压缩代理请求的回应,代理请求的依据是请求头中是否包含Via字段,off表示只要请求头中包含Via字段,则不压缩。
		#gzip_proxied expired;#如果回应中包含头字段Expires,并且其值导致不会缓存,则压缩。
		#注1:该设置不考虑是否在请求中包含Via
		#注2:注1理解是错误的,进入gzip_proxied的先决条件一定是头字段中包含Via字段,以当前的设置,在不考虑gzip_proxied影响的情况下,响应一定是压缩的,所以给人以误解,当gzip_proxied条件满足时无论是否有Via都压缩。
		#回应中添加Expires,注:使用expires指令会同时添加Expires和Cache-Control头字段
		#expires 1h; #缓存有效期1小时
		#expires epoch;#缓存有效期设为1970年1月1日0时,即必然过期,不缓存

		#gzip_proxied no-cache no-store private有类似的行为,如果响应头字段包含Cache-Control: xxx,则压缩
		#有2点需要注意,1.受Via字段影响;2.回应中需要显示地有Cache-Control头字段,如果不包含则压缩
		#gzip_proxied no-cache;
		#gzip_proxied no-store;
		#gzip_proxied private;
		#回应添加Cache-Control用add_header
		#add_header Cache-Control no-store;
		#add_header Cache-Control no-cache;
		#add_header Cache-Control private;
		#可以同时设置多个gzip_proxied条件:
		#gzip_proxied no-cache no-store private;
		#add_header也可以为Cache-Control设置多个值,对于这种有冲突的Cache-Control设置,以最严格的限制为准。
		#add_header Cache-Control no-store,no-cache,private;

		#gzip_proxied no_etag;#如果回应中不包含头字段ETag,则压缩。
		#etag off;
		#未找到关闭last_modified的方法,abort
		#gzip_proxied no_last_modified;
		#if_modified_since off;

		#gzip_proxied any;#对任意代理请求回应压缩。

		gzip_proxied auth;#请求中包含Authorization时压缩
		auth_basic "test for auth_basic";
		auth_basic_user_file ../src/usr;
		#curl -H 'Via: 1.1 aaa' test --compressed --basic -u root:root

		#curl可以使用2种命令行方式验证gzip,一种是添加Accept-Encoding头字段,一种使用compressed参数
		#curl -H 'Accept-Encoding: gzip' test/200_accept_encoding.css --output a.css
		#curl test/200_accept_encoding.css --compressed
		#如果客户端请求不支持的压缩方式如br,则服务器将忽略之

		location / {
			#return 200 'ok\n';#如果使用return,则在gzip模块生效之前就退出,所以不会压缩。
			#Content-Length和Cotnent-Encoding不会同时出现,因为gzip是实时动态压缩,无法预先取得Content-Length。
			#Accept-Encoding实验中curl必须显示的添加Accept-Encoding头字段,否则视为不使用压缩方式返回响应,而浏览器天然会添加Accept-Encoding
			#$gzip_ratio计算的是源文件和压缩文件的大小之比,如源文件100,压缩文件20,则ratio为5
		}

    }


参考:ngx_http_gzip_module

相关文章:一文读懂nginx gzip_static

总结

到此这篇关于一篇文章读懂nginx中gzip功能的文章就介绍到这了,更多相关nginx gzip功能内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一篇文章读懂nginx的gzip功能

本文链接: https://lsjlt.com/news/148637.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一篇文章读懂nginx的gzip功能
    目录前言语义:拓扑:仿真:验证:gzip_proxied的参数解析:小结:总结前言 HTTP中包体【body】压缩协商对应的头字段为Accept-Encoding/Content-E...
    99+
    2024-04-02
  • 一篇文章读懂nginx的gzip_static模块
    Nginx支持静态和动态两种包体gzip压缩方式,分别对应模块ngx_http_gzip_static,ngx_http_gzip。 我们知道gzip是CPU密集型的应用,实时动态压...
    99+
    2024-04-02
  • Java读取excel的方式,一篇文章看懂(详细)
    目录 一、excel读取的两种方式 1.1 jxl 和 poi 的区别和选择 二、jxl 的使用 2.1 导入相关依赖  2.2 操作 三、poi 的使用 3.1 导入相关依赖 3.2 操作 四、总结 一、excel读取的两种方式 J...
    99+
    2023-09-03
    java jar intellij-idea spring
  • 一篇文章读懂Golang init函数执行顺序
    目录1.init 函数简介2.执行顺序2.1 单个源文件的 init 执行顺序2.2 单个包的 init 执行顺序2.3 main 包导入多个包时 init 执行顺序2.3.1 不存...
    99+
    2024-04-02
  • 一篇文章读懂什么是MySQL索引下推(ICP)
    目录一、简介 二、原理 三、实践 3.1 不使用索引下推 3.2 使用索引下推 四、使用条件 五、相关系统参数 总结一、简介 ICP(Index Condition Pushdow...
    99+
    2024-04-02
  • 一篇文章读懂Java哈希与一致性哈希算法
    目录哈希 Hash 算法介绍分布式存储场景场景描述:实现思路:缺点:一致性Hash算法节点增加场景节点减少场景节点分布不均匀虚拟节点增加节点节点减少总结哈希 Hash 算法介绍 哈希...
    99+
    2024-04-02
  • 一篇文章看懂MySQL主从复制与读写分离
    目录引言一、MySQL主从复制1、MySQL的复制类型2、MySQL主从复制的原理3、MySQL主从复制延迟二、MySQL读写分离1、常见的 MySQL 读写分离分2、MySQL 读...
    99+
    2024-04-02
  • 一篇文章弄懂C#中的async和await
    目录前言 async await 从以往知识推导 创建异步任务 创建异步任务并返回Task 异步改同步 说说 await Task 说说 async Task<TResult&...
    99+
    2024-04-02
  • 一篇文章弄懂ECMAScript中的操作符
    目录一元操作符 布尔操作符 乘性操作符 加性操作符 关系操作符 相等操作符 条件操作符 赋值操作符 逗号操作符 总结一元操作符 只能操作一个值的操作符叫做一元操作符 递增和递减。递...
    99+
    2024-04-02
  • 一篇文章搞懂Go语言中的Context
    目录0 前置知识sync.WaitGroup1 简介2 context.Context引入3 context包的其他常用函数3.1 context.Background和contex...
    99+
    2024-04-02
  • 一篇文章弄懂Mybatis中#和$的区别
    目录前言一:下面我们写个关于“#”的个sql,看能不能注入。1.正常传参2.拼接传参二:下面我们写个关于“$”的个sql,看能不能注入。1.正常传参2.拼接传参总结前言 在学校的时候...
    99+
    2024-04-02
  • 一篇文章弄懂js中的typeof用法
    目录基础返回类型string 和 booleannumber 和 bigintsymbolundefinedfunctionobject其他常见问题引用错误typeof nullty...
    99+
    2024-04-02
  • 一篇文章搞懂 push_back 和 emplace_back 的区别
    push_back 和 emplace_back 本来以为自己对 push_back 和 emplace_back 的理解还行,直到我室友伦伦问了一个关于 push_back 和 emplace_back 的问题。死去的 modern ef...
    99+
    2023-08-20
    c++ java 算法
  • 一篇文章弄懂javascript内存泄漏
    1、什么是内存泄漏 在了解什么是内存泄漏之前, 我们应该要对内存是什么有个概念, 随机存取存储器(英语:Random Access Memory,缩写:RAM)是与 CPU 直接交...
    99+
    2024-04-02
  • 一篇文章看懂Vue组合式API
    目录一. 为什么要使用Composition API1.1.一个Options API实例1.2.Options API存在的问题1.3.Composition API简介二.Com...
    99+
    2023-05-14
    vue 组合式api的意义 vue3组合式api教程 vue2使用组合式api
  • 一篇文章让你看懂封装Axios
    目录前言拦截器不要返回数据,依然返回 AxiosResponse 对象不推荐的做法推荐的做法为你的请求添加拓展支持请求重试支持 jsonp 请求支持 URI 版本控制保持请求唯一后语...
    99+
    2024-04-02
  • 一篇文章搞懂MySQL加锁机制
    目录前言锁的分类乐观锁和悲观锁共享锁(S锁)和排他锁(X锁)按加锁粒度区分全局锁表级锁(表锁和MDL锁)意向锁行锁间隙锁next-key lock(临键锁)加锁规则死锁和死锁检测总结...
    99+
    2024-04-02
  • 一篇文章搞懂K8S高级特性
    目录K8S高级特性高级特性总结kubectl排查服务问题K8S真的放弃Docker了吗?K8S高级特性 K8S中还有一些高级特性有必要了解下,比如弹性扩缩应用(见上文)、滚动更新(见...
    99+
    2024-04-02
  • 一篇文章看懂Java异常处理
    目录异常的定义异常的分类异常的处理方法try…catch处理throw 和throws自定义异常总结异常的定义 在java中,异常就是java在编译、运行或运行过程中出现的错误 总共...
    99+
    2024-04-02
  • 一篇文章看懂SQL中的开窗函数
    目录OVER的定义OVER的语法OVER的用法OVER在聚合函数中使用的示例SUM后的开窗函数COUNT后的开窗函数OVER在排序函数中使用的示例ROW_NUMBER()RANK() DENSE_RANK()&...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作