🚀 压缩与解压缩
在 Web 传输中,使用内容编码方法如 gzip
和 brotli
压缩数据是一种常见的优化技术。这两种方法各有其优点和局限性。
🌐 Gzip
-
历史悠久:
gzip
在 web 生态系统中已经使用了很长时间,被绝大多数浏览器和客户端广泛支持。 -
Nginx 支持:
- 压缩:Nginx 可以在运行时压缩内容,减少传输的数据量。
- 解压缩:使用
gunzip
模块,Nginx 也可以解压缩gzip
编码的数据。这主要用于:- 📦 缓存考虑:压缩内容以节省空间,然后在需要时解压缩。
- 🌍 非支持gzip的客户端:为不支持
gzip
的客户端提供未压缩的内容。 - 🔗 与其他后端服务的兼容性:解压缩从其他服务接收到的
gzip
压缩的内容。
🚀 Brotli
-
新兴技术:
brotli
是一个相对较新的压缩方法,为现代浏览器提供更好的压缩率。 -
Nginx 支持:
- 压缩:Nginx 可以使用
brotli
在运行时压缩内容。 - 解压缩:目前,Nginx 本身不支持 Brotli 解压缩功能。如果需要解压缩 Brotli 压缩的内容,可能需要使用其他工具或库。
- 压缩:Nginx 可以使用
🛠 Brotli 解压缩方法
-
命令行工具:使用 Brotli 工具轻松解压
.br
文件。brotli -d compressed_file.br
-
Python:使用 Brotli 库进行编程解压。
import brotli ...
-
Node.js:使用
iltorb
或其他库在 JavaScript 中解压。
🌐 gzip
🔎 概述
压缩过程可以大大减少传输的数据量,从而提高加载速度。但值得注意的是,压缩会增加服务器的处理开销,这在某些情况下可能会影响性能。Nginx 在向客户端发送响应之前会执行压缩,但它会避免对已经压缩过的内容进行双重压缩。
🔽 启用压缩
- 基本启用 🌟:
gzip on;
- 定义 MIME 类型 📄:
- 默认情况下,Nginx 仅对
text/html
类型的内容进行压缩。要对其他类型的内容进行压缩,使用gzip_types
指令:
gzip_types text/plain application/xml;
- 默认情况下,Nginx 仅对
- 设置最小压缩长度 📏:
- 通过
gzip_min_length
指令,你可以定义响应的最小长度来决定是否进行压缩。默认为 20 字节:
gzip_min_length 1000;
- 通过
🔼 启用解压
在某些场景中,你可能会遇到无法处理 gzip
编码响应的客户端,或者需要动态地存储和缓存压缩数据。为了满足这些需求,Nginx 提供了 gunzip
指令以实时解压缩数据。
1️⃣ 为特定路径启用解压
在下面的示例中,任何通过 /storage/
路径请求的 gzip
压缩数据都将被实时解压缩:
# 为特定路径启用解压
server {
listen 80;
server_name example-storage.com;
location /storage/ {
gunzip on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://your_backend_server_address;
}
# 其他 location 块或配置
}
2️⃣ 在服务器配置中启用解压
下面的示例展示了如何在整个 server
块中同时启用 gzip
和 gunzip
:
user nginx;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
sendfile on;
keepalive_timeout 65;
# 为特定路径启用解压
server {
listen 80;
server_name example-storage.com;
location /storage/ {
gunzip on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://your_backend_server_address;
}
# 其他 location 块或配置
}
# 在整个 server 块中启用压缩和解压
server {
listen 80;
server_name example-full.com;
# 开启 gzip 压缩
gzip on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 开启 gunzip 解压缩
gunzip on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://your_backend_server_address;
}
# 其他 location 块或配置
}
}
🚨 注意:确保已经在你的 Nginx 安装中启用了
gunzip
模块。如果使用的是预编译的 Nginx 版本,可能需要检查gunzip
模块是否包含在内,或者可能需要自己编译 Nginx 以包含该模块。
📦 发送压缩文件
-
当你的服务器上有大量静态内容(如 CSS、JavaScript 或 HTML 文件)时,预先压缩这些内容并使用
gzip_static
指令可以显著提高性能。使用gzip_static
指令,Nginx 可以直接发送预先压缩的文件,而不是实时压缩常规文件:user nginx; worker_processes auto; pid /run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; sendfile on; keepalive_timeout 65; # 为静态资源发送预压缩的文件 server { listen 80; server_name your-domain.com; root /path/to/your/web/root; # 开启 gzip_static location / { gzip_static on; try_files $uri $uri/ =404; } # 其他 location 块或配置 } }
在这个配置中,请确保替换
your-domain.com
为您的实际域名,以及/path/to/your/web/root
为您的 web 根目录的路径。此外,确保您的静态资源目录中已预先压缩了文件,并将.gz
版本保存在与原始文件相同的目录中。此配置将使 Nginx 尝试为每个请求发送一个预先压缩的
.gz
文件(如果存在的话)。如果没有找到预压缩的文件或客户端不支持gzip
,它会回退到发送原始文件。
📊 完整示例
-
打开 Nginx 配置文件
你的配置文件的位置可能会根据安装方式和操作系统而异,但常见的位置是
/etc/nginx/nginx.conf
。sudo nano /etc/nginx/nginx.conf
-
在
http
块中添加或修改以下配置:user nginx; worker_processes auto; pid /run/nginx.pid; events { worker_connections 1024; multi_accept on; use epoll; } http { # 设置 MIME 类型 include /etc/nginx/mime.types; default_type application/octet-stream; # 日志设置 access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # 连接设置 sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; # 缓冲区设置 client_max_body_size 10M; client_body_buffer_size 128k; client_header_buffer_size 1k; large_client_header_buffers 4 16k; output_buffers 1 32k; postpone_output 1460; # gzip 压缩设置 gzip on; gzip_comp_level 5; gzip_min_length 256; gzip_proxied any; gzip_vary on; gzip_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component; gzip_disable "MSIE [1-6]\."; # 虚拟主机配置 server { listen 80 default_server; server_name _; root /usr/share/nginx/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } } }
-
保存并关闭配置文件。
-
检查配置的正确性:
sudo nginx -t
如果你看到以下消息,那么你的配置是正确的:
nginx: configuration file /etc/nginx/nginx.conf test is successful
-
重新加载 Nginx:
sudo systemctl reload nginx
🔗 测试
想知道你的 Nginx gzip
配置是否启用成功吗?以下是一些简单有效的方法来验证:
🖥️1. 命令行大师: 使用 curl
使用 curl
命令来检查响应头,看看是否包含 Content-Encoding: gzip
:
curl -I -H "Accept-Encoding: gzip" http://yourdomain.com
如果输出中你看到这样的行:
Content-Encoding: gzip
🎉 恭喜!这意味着 gzip
压缩已成功启用。
🌍 2. 在线工具侦探
有许多在线工具可以帮助你检查:
只需输入你的网站 URL,它们会迅速告诉你是否启用了 gzip
压缩。
🕵️♂️ 3. 浏览器开发者工具探索
现代浏览器的开发者工具是一个宝藏,可以帮助你查看响应头:
- 打开你的目标网页。
- 启动浏览器的开发者工具(通常右键点击页面 ➡️ “检查元素” 或 “开发者工具”)。
- 跳转到 “Network” 标签。
- 刷新页面,观察请求列表。
- 点击与你的网站域名匹配的主文档。
- 在右侧,查看响应头部分,找到
Content-Encoding
。如果它的值是gzip
,那么你知道了答案!
⚡️ brotli
Brotli 是 Google 开发的压缩算法,与 Gzip 相比,它提供了更高的压缩率和更好的性能。重要的是,它主要用于 HTTPS 内容。
📥 1. 下载 Brotli 源码 :
yum install git && cd /usr/local/src
git clone https://github.com/google/ngx_brotli.git
pushd ngx_brotli
git submodule update --init
popd
🔍 2. 查看当前 Nginx 参数 :
执行命令 nginx -V
来查看当前的配置参数。
🛠️ 3. 重新编译 Nginx 以包含 Brotli:
首先,进入你的 Nginx 源代码目录。然后,使用你的配置参数重新编译 Nginx,确保包含 Brotli 模块:
cd nginx-1.16.1
./configure \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_sub_module \
--with-openssl=../openssl-1.1.1c \
--add-module=../ngx_brotli
make && make install
对于需要平滑升级的情况,执行以下命令:
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/nginx
make upgrade
⚙️ 4. 修改 Nginx 配置 :
在你的 nginx.conf
中,启用 Brotli 并设置相关的 MIME 类型:
user nginx;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
# 设置 MIME 类型
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志设置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 连接设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# 缓冲区设置
client_max_body_size 10M;
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
output_buffers 1 32k;
postpone_output 1460;
# Brotli 压缩设置
brotli on;
brotli_comp_level 5;
brotli_static on;
brotli_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
# 虚拟主机配置
server {
listen 80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
}
🔄 5. 重新加载 Nginx 配置 :
nginx -t && nginx -s reload
🔗 6. 测试:
你可以使用 Brotli Test 等在线工具来验证 Brotli 压缩是否正确启用。
💚 同时使用 gzip 和 brotli
当我们考虑网站的性能优化时,内容压缩是提高页面加载速度和降低带宽使用的关键技术之一。在 Nginx 中,你可以使用两种流行的压缩方法:gzip
和 brotli
。
💡 为什么同时考虑 gzip 和 brotli?
-
🌍 广泛支持:虽然 Brotli 为现代浏览器提供了更好的压缩率,但并非所有客户端都支持它。Gzip 是长期以来的标准,被几乎所有的浏览器和客户端支持。
-
🚀 最佳性能:对于支持 Brotli 的客户端,使用 Brotli 可以为用户提供更快的页面加载速度和更小的传输大小。
🛠️ 如何在 Nginx 中配置?
-
确保两个模块都已安装:在使用之前,确保你的 Nginx 安装了
gzip
和ngx_brotli
模块。 -
在 Nginx 配置中启用它们:
user nginx;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
# 设置 MIME 类型
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志设置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 连接设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# Gzip 压缩设置
gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6]\.";
# Brotli 压缩设置
brotli on;
brotli_comp_level 5;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 虚拟主机配置
server {
listen 80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
}
- 重新加载或重启 Nginx 以应用更改。
🔍 客户端如何决定?
当客户端(如浏览器)请求一个资源时,它在 Accept-Encoding
请求头中指示其支持的压缩格式。基于这些信息,Nginx 会选择一个压缩方法。如果客户端支持 Brotli,Nginx 通常会优先选择 Brotli。否则,如果支持 Gzip,Nginx 会选择 Gzip。
🚫 注意事项
-
CPU 负载:压缩会增加服务器的 CPU 负载。如果你的服务器处理大量的请求,确保监控 CPU 使用情况,并根据需要进行调优。
-
预压缩的资源:考虑为常用资源(如 JavaScript 和 CSS 文件)提供预压缩版本。这样,服务器可以直接提供这些文件,而不需要在每次请求时进行实时压缩。
-
HTTPS:Brotli 在大多数情况下仅在 HTTPS 连接上受支持。确保你的网站使用了 SSL/TLS。
⏰ 配置层次结构
1️⃣ http 上下文
-
描述: 定义在
http
上下文中的配置将应用于所有的server
块,除非在特定的server
或location
块中进行了覆盖。 -
示例:
http { gzip on; brotli on; ... }
2️⃣ server 上下文
-
描述: 在
server
上下文中定义的配置只会应用于该特定的server
块。这使得针对不同的虚拟主机进行细粒度配置成为可能。 -
示例:
server { listen 80; server_name example.com; gzip off; brotli off; ... }
3️⃣ location 上下文
-
描述: 在
location
上下文中定义的配置仅应用于匹配该特定位置的请求,这提供了根据请求的具体路径或资源类型的细粒度配置能力。 -
示例:
location /assets/ { gzip on; brotli on; ... }
🔄 gzip 指令
- gzip 🟢
- 描述: 启用或禁用压缩。
- 上下文: http, server, location
- 示例:
gzip on;
- gzip_comp_level 📊
- 描述: 设置压缩级别。
- 上下文: http, server, location
- 示例:
gzip_comp_level 5;
- gzip_min_length 🔢
- 描述: 设置允许压缩的最小响应大小。
- 上下文: http, server, location
- 示例:
gzip_min_length 256;
- gzip_types 📜
- 描述: 压缩响应的 MIME 类型。
- 上下文: http, server, location
- 示例:
gzip_types text/plain application/xml;
- gzip_disable 🚫
- 描述: 根据用户代理禁用压缩。
- 上下文: http, server, location
- 示例:
gzip_disable "MSIE [1-6]\.";
- gzip_static 🗄️
- 描述: 在没有进行实时压缩的情况下,发送预先压缩的文件。
- 上下文: http, server, location
- 示例:
gzip_static on;
- gunzip 🛑
- 描述: 启用或禁用实时解压功能。
- 上下文: http, server, location
- 示例:
gunzip on;
🔄 brotli 指令
- brotli 🟢
- 描述: 启用或禁用 Brotli 压缩。
- 上下文: http, server, location
- 示例:
brotli on;
- brotli_comp_level 📊
- 描述: 设置压缩级别。
- 上下文: http, server, location
- 示例:
brotli_comp_level 6;
- brotli_min_length 🔢
- 描述: 设置允许 Brotli 压缩的最小响应大小。
- 上下文: http, server, location
- 示例:
brotli_min_length 256;
- brotli_types 📜
- 描述: Brotli 压缩响应的 MIME 类型。
- 上下文: http, server, location
- 示例:
brotli_types text/plain application/xml;
- brotli_static 🗄️
- 描述: 在没有进行实时压缩的情况下,发送预先使用 Brotli 压缩的文件。
- 上下文: http, server, location
- 示例:
brotli_static on;
📝 总结:
Nginx 的配置层次结构和覆盖机制为用户提供了强大的灵活性,无论是使用 gzip
还是 brotli
,都可以根据具体需求和策略进行详细的优化。配置的上下文(http
、server
或 location
)决定了这些设置的适用范围。