nginx自编译重现gzip和chunked的现象
前言
最近做项目,发现一个比较好玩的事,nginx的module gzip模式默认支持1KB压缩,和chunked返回,本来现在的很多框架都很完善了,但是,一些新语言框架或者一些老旧框架会不能完整支持chunked,导致出现各种各样的问题,表现为实际已经chunked,但是因为是1KB才触发,所以打上了content-length的属性,但是chunked不能有这个属性,实际也不需要。
自编译
笔者本机是macmini m4,本来也可以brew安装nginx,但是因为ARM cpu的特性,自编译以求最大性能,brew目前不知道有多少是x86的软件。
第一步,下载nginx源码:nginx: download
然后解压执行
./configure
报错
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, 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.
好吧,没安装pcre的包 ,下载:https://sourceforge.net/projects/pcre/
指定路径,当然也可以不使用http_rewrite_module
./configure --with-pcre=./pcre-8.45
然后执行
make
再执行
make install
提示没有权限,加上权限后,因为放在/usr/local/下
cd /usr/local/nginx && ll && pwd
可以设置环境变量,方便直接命令启动
示例
启动nginx需要root权限
sudo ./nginx -c ../conf/nginx.conf
这里的-c config是指从nginx的安装目录查找配置
然后看看nginx加载了哪些模块,实际上因为刚刚启动没加载模块配置,只有编译的默认模块
huahua@huahuadeMac-mini sbin % ./nginx -V
nginx version: nginx/1.26.3
built by clang 16.0.0 (clang-1600.0.26.6)
configure arguments: --with-pcre=./pcre-8.45
默认不gzip
这个时候可以看到nginx没加载什么模块,当然也包括gzip,如果放一些html文件看看
然后执行:localhost:80/1.html
并没有gzip,源文件返回
gzip模块加载
./configure --help | grep gzip
enable表示需要加上模块,disable表示不需要,一般是without开头,表示默认就加载了这个模块
重新编译,加上这些模块,当然生产上尽量多编译一些模块,或者使用别人编译好模块的2进制程序
./configure --with-http_gzip_static_module --with-pcre=./pcre-8.45
这里千万别加上--without-http_gzip_module,我看网上很多说这个约等于--with-http_gzip_static_module,实际不是的,这个without默认状态是disable,表示支持gzip,加上就是without enable,表示不开启gzip
退出nginx,当然也可以指定nginx目录编译,再reload
./configure --prefix=/usr/local/nginx --with-http_gzip_static_module --with-pcre=./pcre-8.45
再执行make,然后nginx reload
此时如果不配置,仍然不会执行gzip,配置如下
# 开启和关闭gzip模式
gzip on;
# gizp压缩起点,文件大于1k才进行压缩
gzip_min_length 1k;
# 设置压缩所需要的缓冲区大小,以4k为单位
gzip_buffers 4 16k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.0;
# gzip 压缩级别,1-9,数字越大压缩的越好,占用CPU时间越长
gzip_comp_level 2;
# 进行压缩的文件类型
gzip_types text/plain application/javascript text/css application/xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
再试一次,请求方把可接受的编码发送出去,其中有gzip(最常用)
服务端,根据自身支持情况,比如gzip,默认1k就压缩了,然后chunked返回
chunked编码的格式
springboot
实际上SpringBoot默认就会使用chunked编码
明显跟nginx有所区别,nginx有大小限制,比如1K,但是SpringBoot默认使用chunked的编码,header跟nginx略有不同,表现为响应header少了nginx的配置内容。
总结
其实gzip并不是最近才有的,以前我们经常压缩html,节省前端资源的传输带宽,只不过最近发现一些老旧项目对chunked支持不友好,导致nginx 1K以上就chunked导致请求报错。然后发现SpringBoot默认就chunked😁。
nginx编译中实际上网上很多内容是复制的,笔者自己实践发现有些参数实际上不应该加上,理解也是跟我们认知有一定的理解偏差,实践发现without 状态要为disable,表示默认已经支持了,不需要加参数, with的模块需要编译加上参数,状态为enable。