这是一个用于测试Nginx Gzip压缩效果的页面。
重复内容有助于提高压缩率。
重复内容有助于提高压缩率。
重复内容有助于提高压缩率。
一、概述
1.1 背景介绍
说起Gzip压缩,可能很多人觉得这是个老生常谈的话题。但我在这几年的运维工作中发现,真正把Gzip配置到位的网站其实不多。去年帮一个客户做性能优化,他们的网站日均带宽消耗在2TB左右,一看Nginx配置,Gzip居然只开了默认的gzip on,压缩级别是1,很多该压的文件类型都没加上。调整完配置后,带宽直接降到800GB,每个月省下来的CDN费用够给团队发几次下午茶了。
Gzip是HTTP/1.1引入的内容编码机制,通过DEFLATE算法对响应体进行压缩。文本类内容(HTML、CSS、JS、JSON、XML)压缩率通常能达到60%-80%,这意味着原本100KB的文件传输时只需要20-40KB。在移动网络环境下,这个优化效果特别明显。
现代浏览器都支持Gzip解压,服务端压缩+客户端解压这个过程对用户来说完全透明,但带来的体验提升却是实实在在的。
1.2 技术特点
压缩原理
Gzip基于LZ77算法和哈夫曼编码,通过查找重复字符串并用更短的引用替代,再对结果进行熵编码。对于包含大量重复模式的文本文件效果最好,对已经压缩过的文件(图片、视频、压缩包)几乎没有效果。
压缩级别
Nginx支持1-9九个压缩级别:
级别1:压缩速度最快,压缩率最低
级别9:压缩率最高,但CPU消耗也最大
级别5-6:通常是性能和压缩率的最佳平衡点
实测数据显示,从级别5到级别9,压缩率只提升3-5%,但CPU消耗增加40%以上。所以生产环境一般不建议用9。
静态预压缩
Nginx的gzip_static模块支持预压缩文件。如果存在file.js.gz,直接返回压缩文件而不用实时压缩,彻底消除CPU开销。这是高并发场景下的杀手级优化。
1.3 适用场景
适合Gzip压缩的内容
HTML/CSS/JavaScript
JSON/XML/SVG
纯文本文件(txt、csv、log)
字体文件(woff虽然已压缩,但gzip还能再压10%左右)
不适合Gzip压缩的内容
图片(JPEG、PNG、WebP本身已压缩)
视频/音频文件
压缩包(zip、gz、rar)
PDF文件(内部已压缩)
典型应用场景
API服务器:JSON响应压缩效果极佳
静态资源服务器:CSS/JS压缩节省大量带宽
文档站点:HTML内容压缩率高
日志分析平台:大量文本数据传输
1.4 环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| 操作系统 | Rocky Linux 9 / Ubuntu 24.04 LTS | 内核4.x以上 |
| Nginx | 1.26.x / 1.27.x | 需包含ngx_http_gzip_module |
| 可选模块 | gzip_static | 静态预压缩支持 |
| 可选模块 | gunzip | 为不支持gzip的客户端解压 |
| CPU | 多核推荐 | 实时压缩消耗CPU |
| 内存 | 每连接约256KB | gzip缓冲区大小 |
二、详细步骤
2.1 准备工作
确认Nginx已编译gzip模块
# 查看编译参数 nginx -V 2>&1 | tr ' ' ' ' | grep gzip # 输出应包含: # --with-http_gzip_static_module # --with-http_gunzip_module # 如果缺少gzip_static模块,需要重新编译或安装带模块的版本 # 官方仓库的nginx默认包含这些模块
准备测试文件
# 创建测试目录 mkdir -p /data/gzip-test # 生成测试文件 cat > /data/gzip-test/test.html << 'EOF'Gzip压缩测试 EOF # 创建一个大的JS文件用于测试 curl -o /data/gzip-test/jquery.js https://code.jquery.com/jquery-3.7.1.js 2>/dev/null || echo'console.log("test");' > /data/gzip-test/jquery.js # 创建JSON测试文件 cat > /data/gzip-test/data.json << 'EOF' { "users": [ {"id": 1, "name": "张三", "email": "zhangsan@example.com"}, {"id": 2, "name": "李四", "email": "lisi@example.com"}, {"id": 3, "name": "王五", "email": "wangwu@example.com"} ], "total": 3, "page": 1, "pageSize": 10 } EOF # 查看文件大小 ls -lh /data/gzip-test/Gzip压缩效果测试页面
这是一个用于测试Nginx Gzip压缩效果的页面。
重复内容有助于提高压缩率。
重复内容有助于提高压缩率。
重复内容有助于提高压缩率。
安装测试工具
# Rocky Linux dnf install curl httpd-tools -y # Ubuntu apt install curl apache2-utils -y
2.2 核心配置
基础Gzip配置
# /etc/nginx/nginx.conf 或 /etc/nginx/conf.d/gzip.conf
http {
# ==================== Gzip基础配置 ====================
# 开启gzip压缩
gzip on;
# 压缩级别:1-9,推荐5-6
# 级别越高压缩率越好但CPU消耗越大
gzip_comp_level 5;
# 最小压缩文件大小
# 小于这个值的文件不压缩(压缩收益小)
gzip_min_length 1024;
# 压缩缓冲区
# 32个4k的缓冲区,用于存储压缩结果
gzip_buffers 32 4k;
# 压缩HTTP版本
# 对HTTP/1.0也启用压缩(兼容老代理)
gzip_http_version 1.0;
# ==================== 压缩类型配置 ====================
# 需要压缩的MIME类型
# 注意:text/html默认已启用,不需要重复添加
gzip_types
# 文本类型
text/plain
text/css
text/xml
text/javascript
# 应用类型
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss
application/xhtml+xml
application/atom+xml
application/rss+xml
# 字体类型
application/font-woff
application/font-woff2
application/vnd.ms-fontobject
application/x-font-ttf
font/opentype
font/woff
font/woff2
# 图片类型(仅SVG,其他图片已压缩)
image/svg+xml
image/x-icon;
# ==================== 代理相关配置 ====================
# 针对代理请求的压缩策略
# any: 对所有代理请求都压缩
gzip_proxied any;
# 其他可选值:
# off: 禁止对代理请求压缩
# expired: 响应头包含Expires且已过期
# no-cache: 响应头包含Cache-Control: no-cache
# no-store: 响应头包含Cache-Control: no-store
# private: 响应头包含Cache-Control: private
# no_last_modified: 响应头不包含Last-Modified
# no_etag: 响应头不包含ETag
# auth: 请求头包含Authorization
# any: 所有代理请求
# ==================== Vary头配置 ====================
# 在响应头中添加Vary: Accept-Encoding
# 告诉代理服务器根据Accept-Encoding缓存不同版本
gzip_vary on;
# ==================== 排除特定客户端 ====================
# 禁止对特定User-Agent压缩
# 某些老旧浏览器对gzip支持有问题
gzip_disable "MSIE [1-6].";
# 也可以用正则排除更多
# gzip_disable "MSIE [1-6].|Mozilla/4";
}
静态预压缩配置(gzip_static)
这是我强烈推荐的优化方式,特别是对于前端构建产物:
http {
# 开启静态预压缩
# on: 查找.gz文件,找到就直接返回
# off: 禁用
# always: 始终返回.gz文件,不检查客户端是否支持
gzip_static on;
server {
listen 80;
server_name example.com;
root /data/www;
# 前端资源目录
location /assets/ {
# 启用静态预压缩
gzip_static on;
# 缓存控制
expires 1y;
add_header Cache-Control "public, immutable";
}
# API接口(实时压缩)
location /api/ {
# API响应需要实时压缩
gzip on;
gzip_comp_level 5;
gzip_types application/json;
proxy_pass http://backend;
}
}
}
预压缩文件生成脚本
#!/bin/bash
# generate_gzip.sh - 生成预压缩文件
STATIC_DIR=${1:-/data/www/assets}
GZIP_LEVEL=${2:-9}
echo"开始生成预压缩文件..."
echo"目录: $STATIC_DIR"
echo"压缩级别: $GZIP_LEVEL"
# 需要预压缩的文件类型
FILE_TYPES="css js html json xml svg txt"
for ext in$FILE_TYPES; do
find "$STATIC_DIR" -name "*.$ext" -type f | whileread file; do
# 跳过已经是.gz的文件
[[ "$file" == *.gz ]] && continue
gz_file="${file}.gz"
# 如果.gz文件不存在或源文件更新,重新压缩
if [[ ! -f "$gz_file" ]] || [[ "$file" -nt "$gz_file" ]]; then
echo"压缩: $file"
gzip -${GZIP_LEVEL} -c "$file" > "$gz_file"
# 保持时间戳一致
touch -r "$file""$gz_file"
fi
done
done
echo"预压缩完成!"
# 统计压缩效果
echo""
echo"=== 压缩效果统计 ==="
find "$STATIC_DIR" -name "*.gz" -type f | whileread gz_file; do
orig_file="${gz_file%.gz}"
if [[ -f "$orig_file" ]]; then
orig_size=$(stat -c%s "$orig_file" 2>/dev/null || stat -f%z "$orig_file")
gz_size=$(stat -c%s "$gz_file" 2>/dev/null || stat -f%z "$gz_file")
ratio=$(echo"scale=2; (1 - $gz_size / $orig_size) * 100" | bc)
echo"$orig_file: $orig_size -> $gz_size (节省 ${ratio}%)"
fi
done
2.3 启动和验证
配置检查
# 检查配置语法 nginx -t # 查看gzip相关配置 nginx -T | grep -i gzip # 重载配置 nginx -s reload
基础验证
# 测试gzip是否生效 # 注意:必须发送Accept-Encoding头 # 不带压缩请求 curl -I http://localhost/test.html # Content-Length: 1234 (原始大小) # 带压缩请求 curl -I -H "Accept-Encoding: gzip" http://localhost/test.html # Content-Encoding: gzip # Content-Length: 456 (压缩后大小) # Vary: Accept-Encoding # 获取完整响应并解压 curl -H "Accept-Encoding: gzip" http://localhost/test.html | gunzip
详细测试脚本
#!/bin/bash
# test_gzip.sh - 测试Gzip压缩效果
URL=${1//localhost}
FILES=("test.html""jquery.js""data.json""style.css")
echo"=== Gzip压缩效果测试 ==="
echo"目标: $URL"
echo""
printf"%-30s %10s %10s %10s
""文件""原始大小""压缩大小""压缩率"
printf"%-30s %10s %10s %10s
""----""--------""--------""------"
for file in"${FILES[@]}"; do
# 获取未压缩大小
orig_size=$(curl -sI "$URL/$file" 2>/dev/null | grep -i content-length | awk '{print $2}' | tr -d '
')
# 获取压缩后大小
gzip_size=$(curl -sI -H "Accept-Encoding: gzip""$URL/$file" 2>/dev/null | grep -i content-length | awk '{print $2}' | tr -d '
')
# 检查是否启用了压缩
encoding=$(curl -sI -H "Accept-Encoding: gzip""$URL/$file" 2>/dev/null | grep -i content-encoding)
if [[ -n "$encoding" ]] && [[ -n "$orig_size" ]] && [[ -n "$gzip_size" ]]; then
ratio=$(echo"scale=1; (1 - $gzip_size / $orig_size) * 100" | bc)
printf"%-30s %10s %10s %9s%%
""$file""$orig_size""$gzip_size""$ratio"
else
printf"%-30s %10s %10s %10s
""$file""$orig_size""${gzip_size:-N/A}""未压缩"
fi
done
压力测试对比
# 无压缩测试 ab -n 10000 -c 100 http://localhost/jquery.js # 记录:Requests per second, Transfer rate # 有压缩测试 ab -n 10000 -c 100 -H "Accept-Encoding: gzip" http://localhost/jquery.js # 记录:Requests per second, Transfer rate # 对比传输量和吞吐量的变化
三、示例代码和配置
3.1 完整配置示例
生产环境完整配置
# /etc/nginx/conf.d/gzip-production.conf
# 生产环境Gzip完整配置
http {
# ==================== Gzip全局配置 ====================
# 基础开关
gzip on;
# 压缩级别:生产环境推荐5
gzip_comp_level 5;
# 最小压缩大小:小于1KB的文件不压缩
gzip_min_length 1024;
# 压缩缓冲区配置
# 16个8k的缓冲区,适合中等大小文件
gzip_buffers 16 8k;
# HTTP版本
gzip_http_version 1.1;
# 启用Vary头
gzip_vary on;
# 对代理请求的处理
gzip_proxied any;
# 禁用对老旧IE的压缩
gzip_disable "MSIE [1-6].(?!.*SV1)";
# 压缩类型(完整列表)
gzip_types
# 文本
text/plain
text/css
text/xml
text/javascript
text/x-component
text/cache-manifest
# 应用
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss
application/xhtml+xml
application/atom+xml
application/rss+xml
application/ld+json
application/manifest+json
application/schema+json
application/geo+json
application/vnd.api+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-font-opentype
application/x-font-truetype
application/x-web-app-manifest+json
# 字体
font/eot
font/opentype
font/otf
font/woff
font/woff2
# 图片(仅矢量)
image/svg+xml
image/x-icon
image/bmp
image/vnd.microsoft.icon;
# ==================== 静态预压缩 ====================
# 全局开启静态预压缩
gzip_static on;
}
分场景配置示例
server {
listen 80;
server_name example.com;
root /data/www;
# ==================== 场景一:静态资源CDN源站 ====================
location /static/ {
# 使用预压缩文件(最高压缩级别)
gzip_static on;
# 如果没有预压缩文件,实时压缩
gzip on;
gzip_comp_level 6;
# 长缓存
expires 1y;
add_header Cache-Control "public, immutable";
}
# ==================== 场景二:API响应压缩 ====================
location /api/ {
# API响应通常是JSON,必须实时压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 256; # API响应可能较小,降低阈值
gzip_types application/json;
# 禁用代理缓存(API响应经常变化)
add_header Cache-Control "no-store";
proxy_pass http://api_backend;
proxy_set_header Accept-Encoding ""; # 不让后端压缩,Nginx统一处理
}
# ==================== 场景三:HTML页面 ====================
location / {
gzip on;
gzip_comp_level 5;
gzip_types text/html;
# HTML不缓存,保证获取最新内容
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri $uri/ /index.html;
}
# ==================== 场景四:大文件下载 ====================
location /downloads/ {
# 大文件不压缩,避免占用大量内存和CPU
gzip off;
# 开启sendfile高效传输
sendfile on;
tcp_nopush on;
# 限速防止带宽耗尽
limit_rate 1m;
}
# ==================== 场景五:WebSocket ====================
location /ws/ {
# WebSocket不能使用gzip
gzip off;
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
3.2 实际应用案例
案例一:电商网站首页优化
我们有个电商客户,首页HTML有800KB(包含大量商品数据),加载时间超过3秒。
优化前的情况:
首页大小: 812KB 加载时间: 3.2s(3G网络) Gzip: 未启用
优化方案:
location / {
gzip on;
gzip_comp_level 6; # 首页访问频繁,适当提高压缩级别
gzip_types text/html application/json;
gzip_min_length 256;
# 启用ETag便于缓存验证
etag on;
try_files $uri @backend;
}
location @backend {
proxy_pass http://backend;
# 后端响应也要压缩
gzip on;
gzip_proxied any;
}
优化后:
首页大小: 812KB -> 156KB(压缩率81%) 加载时间: 3.2s -> 0.8s 带宽节省: 约80%
案例二:API服务压缩优化
某金融APP后端API,每天数千万次调用,返回JSON数据。
问题分析:
平均响应大小: 15KB 日请求量: 5000万次 日带宽消耗: 约700TB 带宽成本: 高
配置方案:
upstream api_servers {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
keepalive 100;
}
server {
listen 80;
server_name api.example.com;
location / {
# JSON响应压缩
gzip on;
gzip_comp_level 5;
gzip_min_length 512;
gzip_types application/json;
gzip_proxied any;
gzip_vary on;
proxy_pass http://api_servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 重要:告诉后端不要压缩,统一由Nginx处理
proxy_set_header Accept-Encoding "identity";
# 缓冲设置,避免边收边发
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 32k;
}
}
优化效果:
平均响应大小: 15KB -> 3KB(压缩率80%) 日带宽消耗: 700TB -> 140TB 月度带宽成本节省: 约560TB * 单价 CPU增加: 约15%(可接受)
案例三:前端构建产物预压缩
现代前端项目使用Webpack/Vite构建,结合CI/CD自动生成预压缩文件。
Vite配置:
// vite.config.js
import { defineConfig } from'vite'
import viteCompression from'vite-plugin-compression'
exportdefault defineConfig({
plugins: [
viteCompression({
algorithm: 'gzip',
ext: '.gz',
threshold: 1024, // 大于1KB才压缩
deleteOriginFile: false// 保留原文件
}),
// 同时生成Brotli压缩
viteCompression({
algorithm: 'brotliCompress',
ext: '.br',
threshold: 1024
})
]
})
Nginx配置:
location /assets/ {
# 优先返回Brotli压缩(压缩率更高)
brotli_static on;
# 其次返回Gzip
gzip_static on;
# 如果都没有,实时压缩
gzip on;
gzip_comp_level 5;
expires max;
add_header Cache-Control "public, immutable";
}
CI/CD pipeline脚本:
#!/bin/bash
# build.sh - 前端构建脚本
# 构建
npm run build
# 生成预压缩文件
cd dist
# Gzip压缩
find . -type f ( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.json" )
-exec gzip -9 -k {} ;
# Brotli压缩(如果安装了brotli)
ifcommand -v brotli &> /dev/null; then
find . -type f ( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.json" )
-exec brotli -9 -k {} ;
fi
# 统计
echo"=== 压缩统计 ==="
du -sh dist/
find dist -name "*.gz" | wc -l
find dist -name "*.br" | wc -l
案例四:不同压缩级别性能对比测试
我在一台4核8G的服务器上做了详细测试,文件是280KB的jquery.min.js:
| 压缩级别 | 压缩后大小 | 压缩率 | 压缩耗时 | QPS |
|---|---|---|---|---|
| 1 | 98KB | 65% | 0.8ms | 12000 |
| 2 | 94KB | 66% | 0.9ms | 11500 |
| 3 | 91KB | 67% | 1.1ms | 10800 |
| 4 | 88KB | 69% | 1.4ms | 9500 |
| 5 | 85KB | 70% | 1.8ms | 8200 |
| 6 | 84KB | 70% | 2.5ms | 6800 |
| 7 | 83KB | 70% | 3.8ms | 5200 |
| 8 | 82KB | 71% | 6.2ms | 3500 |
| 9 | 82KB | 71% | 12ms | 1800 |
| 预压缩 | 82KB | 71% | 0ms | 35000 |
结论:
级别5是性价比最高的选择
级别6-9收益递减明显,不推荐
预压缩性能碾压实时压缩,强烈推荐
四、最佳实践和注意事项
4.1 最佳实践
1. 根据内容类型选择压缩策略
# 高频访问的静态资源:预压缩
location ~* .(js|css)$ {
gzip_static on;
gzip on;
gzip_comp_level 5;
}
# 动态生成的内容:实时压缩
location /api/ {
gzip on;
gzip_comp_level 5;
}
# 已压缩的媒体文件:不压缩
location ~* .(jpg|jpeg|png|gif|mp4|webm|zip|gz)$ {
gzip off;
}
2. 合理设置gzip_min_length
# 太小的文件压缩后可能反而变大(gzip头部开销) # 推荐设置: gzip_min_length 1024; # 通用场景 # API场景可以降低阈值(JSON通常较小但压缩率高) gzip_min_length 256;
3. gzip_vary必须开启
# 必须开启,否则CDN/代理可能返回错误的缓存 gzip_vary on; # 这会在响应头添加: # Vary: Accept-Encoding # 告诉缓存服务器:同一URL根据Accept-Encoding返回不同内容
4. 统一在Nginx层压缩
# 不要让后端应用也压缩,会造成:
# 1. 重复压缩浪费CPU
# 2. 压缩策略不统一
# 3. 调试困难
location /api/ {
proxy_pass http://backend;
# 告诉后端不要压缩
proxy_set_header Accept-Encoding "identity";
# 由Nginx统一压缩
gzip on;
gzip_proxied any;
}
5. 监控压缩效果
# 自定义日志格式记录压缩信息 log_format compression '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$gzip_ratio'; # $gzip_ratio 显示压缩比例,如 "2.50"表示压缩到原来的1/2.5
4.2 注意事项
常见错误表
| 错误 | 原因 | 解决方案 |
|---|---|---|
| gzip不生效 | 请求头缺少Accept-Encoding | 检查客户端/代理是否移除了该头 |
| 压缩率低 | 文件已压缩或内容随机性高 | 检查文件类型,已压缩文件不要重复压缩 |
| CPU飙高 | 压缩级别过高或并发过大 | 降低压缩级别或使用预压缩 |
| 响应变慢 | gzip_buffers配置不当 | 增大缓冲区或降低压缩级别 |
| CDN缓存异常 | 未设置Vary头 | 开启gzip_vary on |
| 部分请求未压缩 | 小于gzip_min_length | 降低阈值或接受不压缩 |
| 乱码 | 客户端不支持gzip | 使用gzip_disable排除 |
性能陷阱
# 陷阱1:对所有内容都压缩 # 错误 gzip_types *; # 正确:只压缩文本类型 # 陷阱2:压缩级别设置过高 # 错误 gzip_comp_level 9; # CPU杀手 # 正确 gzip_comp_level 5; # 性价比最高 # 陷阱3:不限制最小压缩大小 # 错误 gzip_min_length 0; # 所有文件都压缩 # 正确 gzip_min_length 1024; # 小文件不压缩 # 陷阱4:对图片视频压缩 # 错误 gzip_types image/jpeg image/png video/mp4; # 这些格式已经压缩过,再压缩只浪费CPU # 陷阱5:没有预压缩高频文件 # 错误:每次请求都实时压缩 # 正确:构建时预压缩 + gzip_static on
安全考虑
# BREACH攻击防护
# 对包含敏感信息的HTTPS响应,攻击者可能通过压缩率变化推测内容
# 防护方案:
# 1. 对包含敏感数据的响应禁用压缩
location /api/sensitive/ {
gzip off;
}
# 2. 在响应中添加随机填充
# 需要后端配合实现
# 3. 使用SameSite Cookie
add_header Set-Cookie "session=xxx; SameSite=Strict";
五、故障排查和监控
5.1 故障排查
问题一:Gzip完全不生效
# 排查步骤 # 1. 检查模块是否加载 nginx -V 2>&1 | grep -o 'http_gzip_module' # 2. 检查配置是否生效 nginx -T | grep gzip # 3. 测试请求 curl -I -H "Accept-Encoding: gzip" http://localhost/test.html # 4. 如果响应头没有Content-Encoding: gzip,检查: # - gzip是否为on # - 文件类型是否在gzip_types中 # - 文件大小是否大于gzip_min_length # - 是否被gzip_disable规则排除 # 5. 查看错误日志 tail -f /var/log/nginx/error.log
问题二:部分文件未压缩
# 常见原因:MIME类型不在gzip_types中 # 检查文件MIME类型 file --mime-type test.json # application/json # 检查Nginx的MIME配置 cat /etc/nginx/mime.types | grep json # 确保gzip_types包含该类型 nginx -T | grep gzip_types
问题三:压缩后文件变大
# 小文件或高熵内容压缩后可能变大 # 检查原始文件大小 ls -la test.html # 如果小于1KB,提高gzip_min_length # 或者检查文件内容是否已压缩/随机数据
问题四:CPU占用过高
# 检查压缩级别 nginx -T | grep gzip_comp_level # 查看Nginx进程CPU top -p $(pgrep -d',' nginx) # 解决方案: # 1. 降低压缩级别 # 2. 使用预压缩 # 3. 增加gzip_min_length # 4. 限制压缩类型
调试脚本
#!/bin/bash # debug_gzip.sh - Gzip配置调试 URL=$1 if [ -z "$URL" ]; then echo"用法: $0" exit 1 fi echo"=== Gzip调试: $URL ===" echo"" echo"--- 请求头 ---" curl -sI "$URL" | head -20 echo"" echo"--- 带Accept-Encoding的请求 ---" curl -sI -H "Accept-Encoding: gzip, deflate""$URL" | head -20 echo"" echo"--- 关键响应头 ---" echo"Content-Encoding: $(curl -sI -H 'Accept-Encoding: gzip' "$URL" | grep -i content-encoding)" echo"Content-Length (原始): $(curl -sI "$URL" | grep -i content-length)" echo"Content-Length (压缩): $(curl -sI -H 'Accept-Encoding: gzip' "$URL" | grep -i content-length)" echo"Vary: $(curl -sI -H 'Accept-Encoding: gzip' "$URL" | grep -i vary)" echo"" echo"--- 内容类型 ---" echo"Content-Type: $(curl -sI "$URL" | grep -i content-type)"
5.2 性能监控
Nginx状态监控
# 启用状态页
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
压缩率日志
# 记录压缩比例 log_format gzip_log '$remote_addr [$time_local] "$request" ' '$status $body_bytes_sent ' 'gzip_ratio=$gzip_ratio ' 'rt=$request_time'; access_log /var/log/nginx/gzip.log gzip_log;
分析脚本
#!/bin/bash
# analyze_gzip.sh - 分析Gzip压缩效果
LOG_FILE=${1:-/var/log/nginx/gzip.log}
echo"=== Gzip压缩效果分析 ==="
echo""
echo"--- 压缩比例分布 ---"
awk '{
for(i=1;i<=NF;i++) {
if($i ~ /gzip_ratio=/) {
split($i, a, "=")
ratio = a[2]
if (ratio == "-") {
none++
} else if (ratio < 1.5) {
low++
} else if (ratio < 3) {
medium++
} else {
high++
}
}
}
}
END {
total = none + low + medium + high
printf "未压缩: %d (%.1f%%)
", none, none/total*100
printf "低压缩(<1.5x): %d (%.1f%%)
", low, low/total*100
printf "中压缩(1.5-3x): %d (%.1f%%)
", medium, medium/total*100
printf "高压缩(>3x): %d (%.1f%%)
", high, high/total*100
}'$LOG_FILE
echo""
echo"--- 按文件类型统计 ---"
awk '{
# 提取URL和压缩比
url = $5
gsub(/"/, "", url)
for(i=1;i<=NF;i++) {
if($i ~ /gzip_ratio=/) {
split($i, a, "=")
ratio = a[2]
}
}
# 提取扩展名
n = split(url, parts, ".")
ext = parts[n]
n = split(ext, parts, "?")
ext = parts[1]
if (ratio != "-" && ratio > 0) {
count[ext]++
sum[ext] += ratio
}
}
END {
printf "%-10s %10s %15s
", "类型", "请求数", "平均压缩比"
for (ext in count) {
printf "%-10s %10d %15.2f
", ext, count[ext], sum[ext]/count[ext]
}
}'$LOG_FILE | sort -t$' ' -k2 -rn
Prometheus监控指标
# prometheus.yml 抓取配置 scrape_configs: -job_name:'nginx' static_configs: -targets:['localhost:9113'] # 自定义指标(需要nginx-prometheus-exporter) # nginx_http_requests_total # nginx_connections_active # nginx_connections_reading # nginx_connections_writing
5.3 备份与恢复
配置备份
#!/bin/bash # backup_gzip_config.sh BACKUP_DIR="/backup/nginx/gzip" DATE=$(date +%Y%m%d) mkdir -p $BACKUP_DIR # 备份gzip相关配置 nginx -T | grep -A 100 'gzip' > $BACKUP_DIR/gzip_config_$DATE.txt # 备份完整配置 cp -r /etc/nginx/conf.d/ $BACKUP_DIR/conf.d_$DATE/ # 保留30天 find $BACKUP_DIR -mtime +30 -delete echo"备份完成: $BACKUP_DIR"
快速回滚
#!/bin/bash # rollback_gzip.sh - 回滚到默认gzip配置 cat > /etc/nginx/conf.d/gzip.conf << 'EOF' # Gzip默认配置 gzip on; gzip_comp_level 5; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript text/xml; gzip_vary on; EOF nginx -t && nginx -s reload echo "已回滚到默认gzip配置"
六、总结
6.1 技术要点回顾
Gzip压缩优化的核心就是这几点:
选对压缩级别:生产环境用5-6,别用9
选对压缩类型:只压缩文本类,别碰图片视频
用好预压缩:高频访问的静态资源必须预压缩
开启Vary头:gzip_vary on 必须有
统一入口压缩:在Nginx层统一处理,后端不压缩
关键配置速记:
gzip on; gzip_comp_level 5; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript; gzip_vary on; gzip_static on;
6.2 进阶学习方向
Brotli压缩:比Gzip压缩率高15-20%,现代浏览器都支持
Zstd压缩:Facebook开源的新一代压缩算法
动态压缩级别:根据CPU负载动态调整压缩级别
边缘压缩:在CDN边缘节点进行压缩
6.3 参考资料
Nginx Gzip模块文档:https://nginx.org/en/docs/http/ngx_http_gzip_module.html
Gzip vs Brotli对比:https://www.keycdn.com/blog/brotli-compression
HTTP压缩机制RFC:https://tools.ietf.org/html/rfc7231#section-3.1.2.2
BREACH攻击说明:https://breachattack.com/
附录
A. 命令速查表
| 命令 | 说明 |
|---|---|
| gzip -9 file.js | 压缩文件(最高级别) |
| gzip -k file.js | 压缩并保留原文件 |
| gzip -l file.js.gz | 查看压缩信息 |
| gunzip file.js.gz | 解压文件 |
| zcat file.js.gz | 查看压缩文件内容 |
| curl -I -H "Accept-Encoding: gzip" URL | 测试gzip是否生效 |
B. 配置参数详解
| 参数 | 默认值 | 说明 |
|---|---|---|
| gzip | off | 开启/关闭gzip |
| gzip_comp_level | 1 | 压缩级别1-9 |
| gzip_min_length | 20 | 最小压缩大小(字节) |
| gzip_buffers | 32 4k | 压缩缓冲区配置 |
| gzip_types | text/html | 压缩的MIME类型 |
| gzip_vary | off | 是否添加Vary头 |
| gzip_proxied | off | 代理请求压缩策略 |
| gzip_disable | - | 禁用压缩的User-Agent |
| gzip_http_version | 1.1 | 启用压缩的最低HTTP版本 |
| gzip_static | off | 静态预压缩开关 |
C. 术语表
| 术语 | 解释 |
|---|---|
| Gzip | GNU zip,一种基于DEFLATE算法的压缩格式 |
| DEFLATE | 结合LZ77和霍夫曼编码的压缩算法 |
| Content-Encoding | HTTP响应头,指示内容的编码方式 |
| Accept-Encoding | HTTP请求头,告知服务器客户端支持的编码 |
| Vary | HTTP响应头,指示缓存应根据哪些请求头区分响应 |
| Transfer-Encoding | 传输编码,chunked表示分块传输 |
| MIME Type | 多用途互联网邮件扩展类型,标识内容格式 |
| Brotli | Google开发的新一代压缩算法,压缩率优于Gzip |
全部0条评论
快来发表一下你的评论吧 !