Nginx 压缩和解压


🚀 压缩与解压缩

在 Web 传输中,使用内容编码方法如 gzipbrotli 压缩数据是一种常见的优化技术。这两种方法各有其优点和局限性。


🌐 Gzip

  • 历史悠久gzip 在 web 生态系统中已经使用了很长时间,被绝大多数浏览器和客户端广泛支持。

  • Nginx 支持

    • 压缩:Nginx 可以在运行时压缩内容,减少传输的数据量。
    • 解压缩:使用 gunzip 模块,Nginx 也可以解压缩 gzip 编码的数据。这主要用于:
      • 📦 缓存考虑:压缩内容以节省空间,然后在需要时解压缩。
      • 🌍 非支持gzip的客户端:为不支持 gzip 的客户端提供未压缩的内容。
      • 🔗 与其他后端服务的兼容性:解压缩从其他服务接收到的 gzip 压缩的内容。

🚀 Brotli

  • 新兴技术brotli 是一个相对较新的压缩方法,为现代浏览器提供更好的压缩率。

  • Nginx 支持

    • 压缩:Nginx 可以使用 brotli 在运行时压缩内容。
    • 解压缩:目前,Nginx 本身不支持 Brotli 解压缩功能。如果需要解压缩 Brotli 压缩的内容,可能需要使用其他工具或库。

🛠 Brotli 解压缩方法

  1. 命令行工具:使用 Brotli 工具轻松解压 .br 文件。

    brotli -d compressed_file.br
    
  2. Python:使用 Brotli 库进行编程解压。

    import brotli
    ...
    
  3. Node.js:使用 iltorb 或其他库在 JavaScript 中解压。


🌐 gzip

在这里插入图片描述


🔎 概述

压缩过程可以大大减少传输的数据量,从而提高加载速度。但值得注意的是,压缩会增加服务器的处理开销,这在某些情况下可能会影响性能。Nginx 在向客户端发送响应之前会执行压缩,但它会避免对已经压缩过的内容进行双重压缩。


🔽 启用压缩

  1. 基本启用 🌟:
    gzip on;
    
  2. 定义 MIME 类型 📄:
    • 默认情况下,Nginx 仅对 text/html 类型的内容进行压缩。要对其他类型的内容进行压缩,使用 gzip_types 指令:
    gzip_types text/plain application/xml;
    
  3. 设置最小压缩长度 📏:
    • 通过 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 块中同时启用 gzipgunzip

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,它会回退到发送原始文件。


📊 完整示例

  1. 打开 Nginx 配置文件

    你的配置文件的位置可能会根据安装方式和操作系统而异,但常见的位置是 /etc/nginx/nginx.conf

    sudo nano /etc/nginx/nginx.conf
    
  2. 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;
           }
       }
    }
    
  3. 保存并关闭配置文件

  4. 检查配置的正确性:

    sudo nginx -t
    

    如果你看到以下消息,那么你的配置是正确的:

    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
  5. 重新加载 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 中,你可以使用两种流行的压缩方法:gzipbrotli


💡 为什么同时考虑 gzip 和 brotli?

  • 🌍 广泛支持:虽然 Brotli 为现代浏览器提供了更好的压缩率,但并非所有客户端都支持它。Gzip 是长期以来的标准,被几乎所有的浏览器和客户端支持。

  • 🚀 最佳性能:对于支持 Brotli 的客户端,使用 Brotli 可以为用户提供更快的页面加载速度和更小的传输大小。


🛠️ 如何在 Nginx 中配置?

  1. 确保两个模块都已安装:在使用之前,确保你的 Nginx 安装了 gzipngx_brotli 模块。

  2. 在 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;
        }
    }
}
  1. 重新加载或重启 Nginx 以应用更改。

🔍 客户端如何决定?

当客户端(如浏览器)请求一个资源时,它在 Accept-Encoding 请求头中指示其支持的压缩格式。基于这些信息,Nginx 会选择一个压缩方法。如果客户端支持 Brotli,Nginx 通常会优先选择 Brotli。否则,如果支持 Gzip,Nginx 会选择 Gzip。

🚫 注意事项

  • CPU 负载:压缩会增加服务器的 CPU 负载。如果你的服务器处理大量的请求,确保监控 CPU 使用情况,并根据需要进行调优。

  • 预压缩的资源:考虑为常用资源(如 JavaScript 和 CSS 文件)提供预压缩版本。这样,服务器可以直接提供这些文件,而不需要在每次请求时进行实时压缩。

  • HTTPS:Brotli 在大多数情况下仅在 HTTPS 连接上受支持。确保你的网站使用了 SSL/TLS。


⏰ 配置层次结构


1️⃣ http 上下文

  • 描述: 定义在 http 上下文中的配置将应用于所有的 server 块,除非在特定的 serverlocation 块中进行了覆盖。

  • 示例:

    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 指令

  1. gzip 🟢
    • 描述: 启用或禁用压缩。
    • 上下文: http, server, location
    • 示例: gzip on;
  2. gzip_comp_level 📊
    • 描述: 设置压缩级别。
    • 上下文: http, server, location
    • 示例: gzip_comp_level 5;
  3. gzip_min_length 🔢
    • 描述: 设置允许压缩的最小响应大小。
    • 上下文: http, server, location
    • 示例: gzip_min_length 256;
  4. gzip_types 📜
    • 描述: 压缩响应的 MIME 类型。
    • 上下文: http, server, location
    • 示例: gzip_types text/plain application/xml;
  5. gzip_disable 🚫
    • 描述: 根据用户代理禁用压缩。
    • 上下文: http, server, location
    • 示例: gzip_disable "MSIE [1-6]\.";
  6. gzip_static 🗄️
    • 描述: 在没有进行实时压缩的情况下,发送预先压缩的文件。
    • 上下文: http, server, location
    • 示例: gzip_static on;
  7. gunzip 🛑
    • 描述: 启用或禁用实时解压功能。
    • 上下文: http, server, location
    • 示例: gunzip on;

🔄 brotli 指令

  1. brotli 🟢
    • 描述: 启用或禁用 Brotli 压缩。
    • 上下文: http, server, location
    • 示例: brotli on;
  2. brotli_comp_level 📊
    • 描述: 设置压缩级别。
    • 上下文: http, server, location
    • 示例: brotli_comp_level 6;
  3. brotli_min_length 🔢
    • 描述: 设置允许 Brotli 压缩的最小响应大小。
    • 上下文: http, server, location
    • 示例: brotli_min_length 256;
  4. brotli_types 📜
    • 描述: Brotli 压缩响应的 MIME 类型。
    • 上下文: http, server, location
    • 示例: brotli_types text/plain application/xml;
  5. brotli_static 🗄️
    • 描述: 在没有进行实时压缩的情况下,发送预先使用 Brotli 压缩的文件。
    • 上下文: http, server, location
    • 示例: brotli_static on;

📝 总结:
Nginx 的配置层次结构和覆盖机制为用户提供了强大的灵活性,无论是使用 gzip 还是 brotli,都可以根据具体需求和策略进行详细的优化。配置的上下文(httpserverlocation)决定了这些设置的适用范围。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yueerba126

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值