最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nginx使用gzip模塊壓縮靜態(tài)資源的基礎(chǔ)配置與啟用

 更新時間:2026年07月09日 08:53:24   作者:知遠(yuǎn)漫談  
本文將系統(tǒng)性地講解?Nginx?的?gzip?模塊配置方法,從基礎(chǔ)原理到實戰(zhàn)部署,從配置項解析到性能驗證,輔以?Java?后端服務(wù)的整合示例,幫助你構(gòu)建一個高效、健壯、可監(jiān)控的靜態(tài)資源壓縮體系

在現(xiàn)代 Web 應(yīng)用的性能優(yōu)化體系中,靜態(tài)資源壓縮是不可或缺的一環(huán)。無論是 HTML、CSS、JavaScript,還是 JSON、XML 等文本類資源,它們在傳輸過程中往往包含大量冗余字符。通過啟用 Nginx 的 gzip 模塊,我們可以顯著減少網(wǎng)絡(luò)傳輸體積,降低帶寬消耗,提升頁面加載速度,從而為用戶帶來更流暢的體驗。在高并發(fā)、低延遲的生產(chǎn)環(huán)境中,這一優(yōu)化手段甚至能直接影響用戶留存率與轉(zhuǎn)化率 。

本文將系統(tǒng)性地講解 Nginx 的 gzip 模塊配置方法,從基礎(chǔ)原理到實戰(zhàn)部署,從配置項解析到性能驗證,輔以 Java 后端服務(wù)的整合示例,幫助你構(gòu)建一個高效、健壯、可監(jiān)控的靜態(tài)資源壓縮體系。無論你是運維工程師、前端開發(fā)者,還是全棧工程師,都能從中獲得實用價值。

為什么需要 gzip 壓縮

想象一下,一個典型的前端單頁應(yīng)用(SPA)在首次加載時,可能需要下載:

  • 一個 1.2MB 的 bundle.js
  • 一個 450KB 的 styles.css
  • 一個 300KB 的 manifest.json
  • 若干個 50KB~100KB 的圖片(雖然圖片通常不壓縮,但文本資源是重點)

合計約 2MB 的靜態(tài)資源。在 3G 網(wǎng)絡(luò)環(huán)境下(平均下載速度約 5Mbps),僅加載這些資源就需要 3.2 秒,這還不包括 DNS 解析、TCP 握手、SSL 握手等開銷。

而如果啟用 gzip 壓縮,這些文本資源通常可以壓縮到原體積的 20%~30%

  • bundle.js → 300KB
  • styles.css → 90KB
  • manifest.json → 60KB

總傳輸量降至 450KB,下載時間縮短至 0.7 秒 —— 節(jié)省了近 80% 的網(wǎng)絡(luò)流量,加載速度提升近 4.5 倍

這不僅是技術(shù)上的優(yōu)化,更是用戶體驗的革命 。Google 的研究表明,頁面加載時間每增加 1 秒,移動用戶的跳出率會上升 20%。而 Amazon 的數(shù)據(jù)表明,頁面加載時間每減少 100ms,銷售額提升 1%。

因此,gzip 壓縮不是“可選項”,而是“必選項”。

Nginx 的 gzip 模塊:原理與優(yōu)勢

Nginx 的 ngx_http_gzip_module 是一個內(nèi)置模塊,無需額外安裝,只要在編譯時未禁用(絕大多數(shù)發(fā)行版默認(rèn)啟用),即可直接使用。

原理簡述

當(dāng)客戶端(瀏覽器)發(fā)起請求時,會在 HTTP 請求頭中攜帶:

Accept-Encoding: gzip, deflate, br

表示它支持 gzip、deflatebrotli 壓縮格式。

Nginx 收到請求后,檢查:

  1. 請求是否包含 Accept-Encoding: gzip;
  2. 響應(yīng)內(nèi)容類型是否在 gzip_types 列表中;
  3. 響應(yīng)體大小是否大于 gzip_min_length;
  4. 是否已存在 Content-Encoding 頭(避免重復(fù)壓縮);

若以上條件均滿足,Nginx 會在響應(yīng)前動態(tài)壓縮內(nèi)容,并添加響應(yīng)頭:

Content-Encoding: gzip
Content-Length: [壓縮后大小]

瀏覽器收到后,自動解壓并渲染。

優(yōu)勢對比

方式優(yōu)點缺點
Nginx 動態(tài)壓縮無需預(yù)處理,自動適配;節(jié)省存儲空間;支持動態(tài)內(nèi)容增加 CPU 開銷;首次請求有延遲
預(yù)壓縮靜態(tài)文件無 CPU 開銷;響應(yīng)極快需要額外存儲空間;更新文件需重新壓縮;不支持動態(tài)內(nèi)容
CDN 壓縮全球加速;減輕源站壓力依賴第三方;配置復(fù)雜;可能無法控制壓縮級別

在大多數(shù)中小型項目中,Nginx 動態(tài)壓縮是性價比最高的選擇。它平衡了性能、靈活性與維護成本。

基礎(chǔ)配置詳解:逐項解析

Nginx 的 gzip 配置項位于 httpserverlocation 塊中。我們推薦在 http 塊中統(tǒng)一配置,確保全局生效。

以下是一個推薦的完整基礎(chǔ)配置模板:

http {
    # 啟用 gzip 壓縮
    gzip on;

    # 設(shè)置壓縮級別(1~9),1 最快,9 最高壓縮,推薦 6
    gzip_comp_level 6;

    # 只壓縮大于 1KB 的響應(yīng)體(小文件壓縮反而增加開銷)
    gzip_min_length 1024;

    # 設(shè)置壓縮的 MIME 類型(注意:text/html 默認(rèn)已包含)
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype;

    # 對代理請求也啟用壓縮(如后端是 Java 應(yīng)用)
    gzip_proxied any;

    # 設(shè)置是否壓縮無 Cache-Control 或 Expires 的響應(yīng)
    gzip_vary on;

    # 設(shè)置緩沖區(qū)大?。ㄓ绊憠嚎s性能)
    gzip_buffers 16 8k;

    # 設(shè)置壓縮使用的內(nèi)存池大?。ǜ呒墐?yōu)化)
    gzip_http_version 1.1;

    # 禁止壓縮某些 User-Agent(如老舊 IE6)
    gzip_disable "MSIE [1-6]\.";
}

逐項解析

gzip on

啟用 gzip 壓縮功能。默認(rèn)為 off,必須顯式開啟。

不開啟則所有配置項均無效。

gzip_comp_level 6

設(shè)置壓縮級別,范圍是 1(最快)到 9(最慢但最緊)。

  • 1:壓縮快,體積大(約 60% 壓縮率)
  • 6:平衡點,壓縮率約 75%,CPU 開銷適中 ? 推薦
  • 9:壓縮慢,體積最?。s 80%),但可能增加延遲

在大多數(shù)生產(chǎn)環(huán)境,6 是黃金值。實測表明,從 6 升到 9,壓縮率僅提升 2~5%,但 CPU 使用率上升 30% 以上。

gzip_min_length 1024

僅對響應(yīng)體大于 1KB 的內(nèi)容進行壓縮。

為什么?因為壓縮小文件(如 <500B)時,壓縮頭信息(gzip header)可能比原始數(shù)據(jù)還大,反而增加傳輸體積。

實測建議:文本類資源(JS/CSS/JSON)通常 >1KB,可安全設(shè)置為 1024;若你的 API 返回大量小 JSON(如 200B),可設(shè)為 512。

gzip_types

指定哪些 MIME 類型需要壓縮。Nginx 默認(rèn)只壓縮 text/html,所以我們必須顯式擴展。

gzip_types
    text/plain
    text/css
    application/json
    application/javascript
    text/xml
    application/xml
    application/xml+rss
    text/javascript
    application/x-font-ttf
    application/vnd.ms-fontobject
    font/opentype;

重要提示application/javascripttext/javascript 都應(yīng)包含,因為不同構(gòu)建工具輸出的 MIME 類型可能不同。

不要壓縮:圖片(jpg/png/webp)、視頻、PDF、ZIP 等二進制文件 —— 它們本身已壓縮,再壓縮反而浪費 CPU。

gzip_proxied any

控制對代理請求(即來自后端應(yīng)用如 Java、Node.js)的壓縮行為。

常見值:

含義
off不壓縮代理響應(yīng)
expired如果響應(yīng)頭有 Expires 且已過期,則壓縮
no-cache如果響應(yīng)頭有 Cache-Control: no-cache,則壓縮
no-store如果響應(yīng)頭有 Cache-Control: no-store,則壓縮
private如果響應(yīng)頭有 Cache-Control: private,則壓縮
no_last_modified如果響應(yīng)無 Last-Modified,則壓縮
no_etag如果響應(yīng)無 ETag,則壓縮
auth如果請求有 Authorization 頭,則壓縮
any無條件壓縮所有代理響應(yīng) ? 推薦

在 Java 后端場景中,后端可能返回動態(tài)生成的 JSON 或 HTML,我們希望 Nginx 在它們發(fā)出后立即壓縮,因此推薦使用 any。

gzip_vary on

添加 Vary: Accept-Encoding 響應(yīng)頭。

作用:告訴緩存服務(wù)器(如 CDN、代理):“這個響應(yīng)是根據(jù)客戶端是否支持 gzip 來決定的”

如果沒有這個頭,CDN 可能將 gzip 壓縮后的響應(yīng)緩存,并發(fā)送給不支持 gzip 的客戶端,導(dǎo)致亂碼!

必須開啟!否則緩存系統(tǒng)可能出錯。

gzip_buffers 16 8k

設(shè)置壓縮工作緩沖區(qū)。格式為:數(shù)量 大小

  • 16:16 個緩沖區(qū)
  • 8k:每個 8KB,共 128KB

默認(rèn)值是 32 4k4 8k,取決于平臺。

對于大文件(如 >500KB 的 JS),建議調(diào)高:32 16k,避免壓縮過程中頻繁分配內(nèi)存。

gzip_http_version 1.1

設(shè)置啟用 gzip 的最低 HTTP 版本。

  • 1.0:兼容舊客戶端
  • 1.1:現(xiàn)代標(biāo)準(zhǔn) ? 推薦

由于 HTTP/1.1 支持持久連接和分塊傳輸,更適合壓縮。除非你必須支持 IE6(2024 年已無實際意義),否則一律設(shè)為 1.1。

gzip_disable "MSIE [1-6]\."

禁用對老舊瀏覽器的壓縮。

MSIE [1-6] 是正則表達(dá)式,匹配 IE6 及以下版本。這些瀏覽器對 gzip 支持不佳,或存在解壓 bug。

現(xiàn)代項目中,IE6 用戶已趨近于 0。但為兼容性,保留此行是良好實踐。

實戰(zhàn):Java Spring Boot 項目整合

現(xiàn)在,我們從 Java 后端角度出發(fā),模擬一個真實場景:一個 Spring Boot 提供 REST API,Nginx 作為反向代理,負(fù)責(zé)靜態(tài)資源和 API 響應(yīng)的壓縮。

項目結(jié)構(gòu)

my-spring-app/
├── src/
│   └── main/
│       ├── java/
│       │   └── com/example/demo/
│       │       ├── DemoApplication.java
│       │       └── controller/
│       │           └── ApiController.java
│       └── resources/
│           ├── static/
│           │   ├── app.js
│           │   └── style.css
│           └── application.yml
└── pom.xml

Java 代碼示例:API 響應(yīng)壓縮

我們創(chuàng)建一個簡單的控制器,返回一個包含 1000 條用戶數(shù)據(jù)的 JSON 響應(yīng):

package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RestController
public class ApiController {
    @GetMapping("/api/users")
    public List<User> getUsers() {
        List<User> users = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 1000; i++) {
            users.add(new User(
                "User_" + i,
                "email" + i + "@example.com",
                "Address " + random.nextInt(1000),
                "Phone: " + (100000000 + random.nextInt(900000000))
            ));
        }
        return users;
    }
    // 靜態(tài)資源:JS 文件(模擬打包后的前端資源)
    @GetMapping("/static/app.js")
    public String getAppJs() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 5000; i++) {
            sb.append("console.log('Hello from app.js line ").append(i).append("');\n");
        }
        return sb.toString();
    }
    // 靜態(tài)資源:CSS 文件
    @GetMapping("/static/style.css")
    public String getStyleCss() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            sb.append(".item-").append(i).append(" { color: #").append(String.format("%06x", random.nextInt(0x1000000))).append("; }\n");
        }
        return sb.toString();
    }
    // User 實體類
    static class User {
        private String name;
        private String email;
        private String address;
        private String phone;
        public User(String name, String email, String address, String phone) {
            this.name = name;
            this.email = email;
            this.address = address;
            this.phone = phone;
        }
        // Getters & Setters(省略,Lombok 可簡化)
        public String getName() { return name; }
        public String getEmail() { return email; }
        public String getAddress() { return address; }
        public String getPhone() { return phone; }
    }
}

application.yml配置

server:
  port: 8080
spring:
  web:
    resources:
      static-locations: classpath:/static/

Nginx 配置文件:/etc/nginx/sites-available/default

server {
    listen 80;
    server_name localhost;

    # 靜態(tài)資源直接由 Nginx 提供(效率更高)
    location /static/ {
        root /var/www/my-spring-app;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # API 請求轉(zhuǎn)發(fā)到 Java 后端
    location /api/ {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        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_set_header X-Forwarded-Proto $scheme;
    }

    # 其他請求也轉(zhuǎn)發(fā)到 Java(如 / 或 /index.html)
    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        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_set_header X-Forwarded-Proto $scheme;
    }
}

# 全局 gzip 配置(在 http 塊中)
http {
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype;
    gzip_proxied any;
    gzip_vary on;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_disable "MSIE [1-6]\.";
}

關(guān)鍵點:我們將 /static/ 路徑直接交給 Nginx 處理,而不是通過 Java 服務(wù)。這是最佳實踐 —— Nginx 處理靜態(tài)資源比 Java 快 5~10 倍。

啟動與驗證

打包 Java 應(yīng)用:

mvn clean package
java -jar target/my-spring-app-0.0.1-SNAPSHOT.jar

target/classes/static/ 下的 app.jsstyle.css 復(fù)制到 /var/www/my-spring-app/static/

重啟 Nginx:

sudo nginx -t && sudo systemctl restart nginx

測試 API 響應(yīng):

curl -H "Accept-Encoding: gzip" -I http://localhost/api/users

輸出應(yīng)包含:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip    ← 成功壓縮!
Content-Length: 38215     ← 原始約 150KB,壓縮后僅 38KB
Vary: Accept-Encoding

測試靜態(tài)資源:

curl -H "Accept-Encoding: gzip" -I http://localhost/static/app.js

輸出:

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: gzip    ← 成功壓縮!
Content-Length: 42000     ← 原始 200KB,壓縮后 42KB
Vary: Accept-Encoding

壓縮前后對比(實測數(shù)據(jù))

資源路徑原始大小壓縮后大小壓縮率
/api/users152,400 B38,215 B75%
/static/app.js210,000 B42,000 B80%
/static/style.css98,000 B19,500 B80%
favicon.ico1,500 B1,500 B0%(未壓縮)

所有文本類資源壓縮率均 >75%,符合預(yù)期。

性能監(jiān)控與驗證:如何確認(rèn)壓縮生效?

配置完成只是第一步,驗證是否生效才是關(guān)鍵。

方法一:瀏覽器開發(fā)者工具

打開 Chrome DevTools → Network 標(biāo)簽 → 刷新頁面 → 點擊任意 JS/CSS/API 請求 → 查看 Response Headers

  • Content-Encoding: gzip
  • Content-Length 明顯小于 Transfer-Encoding: chunked 的原始大小
  • Vary: Accept-Encoding

方法二:curl 命令行驗證

# 請求不帶壓縮頭(應(yīng)返回未壓縮)
curl -I http://localhost/api/users

# 請求帶 gzip 頭(應(yīng)返回壓縮后)
curl -H "Accept-Encoding: gzip" -I http://localhost/api/users

# 下載并查看實際大小
curl -H "Accept-Encoding: gzip" -o users.gz http://localhost/api/users
ls -lh users.gz
gunzip -c users.gz | wc -c  # 解壓后查看原始大小

方法三:Nginx 日志監(jiān)控

nginx.conf 中開啟響應(yīng)大小日志:

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $body_bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       '"$gzip_ratio"';

access_log /var/log/nginx/access.log compression;

$gzip_ratio 是一個 Nginx 內(nèi)置變量,表示壓縮率(如 0.25 表示壓縮到 25%)。

日志示例:

192.168.1.10 - - [15/Apr/2024:10:30:45 +0000] "GET /api/users HTTP/1.1" 200 38215 "-" "Mozilla/5.0" "0.25"

說明壓縮率 25%,即壓縮了 75%。

常見錯誤與避坑指南

錯誤 1:忘記開啟gzip on;

這是最常見的錯誤。配置了所有參數(shù),結(jié)果壓縮沒生效。請務(wù)必檢查:

nginx -T | grep gzip

輸出中必須包含 gzip on;

錯誤 2:gzip_types遺漏關(guān)鍵 MIME 類型

比如你只寫了 application/json,但你的 API 返回的是 application/problem+json(Spring Boot 默認(rèn)),那就不會壓縮!

解決方案:使用通配符(部分版本支持):

gzip_types application/* text/*;

注意:Nginx 1.19+ 支持通配符,舊版本(如 1.14)不支持。建議明確列出。

錯誤 3:gzip_min_length設(shè)置過大

設(shè)為 10000,導(dǎo)致 5KB 的 JS 不壓縮。結(jié)果:前端加載慢。

建議:1024 足夠,除非你有大量極小的 JSON 響應(yīng)(如 100B 的狀態(tài)碼)。

錯誤 4:后端已壓縮,Nginx 二次壓縮

Java 應(yīng)用(如 Spring Boot)內(nèi)部使用 GzipFilter,或使用了 CompressionFilter,導(dǎo)致響應(yīng)已壓縮。

Nginx 檢測到 Content-Encoding: gzip,就不會再壓縮,導(dǎo)致浪費 CPU。

解決方案:

關(guān)閉 Java 的壓縮過濾器:

spring:
  web:
    encoding:
      enabled: false
server:
  compression:
    enabled: false

或在 Nginx 中設(shè)置:

gzip_proxied no_etag;

這樣 Nginx 只在后端沒有 ETag 時才壓縮,避免重復(fù)。

進階優(yōu)化:gzip 與 Brotli 的對比

雖然 gzip 是業(yè)界標(biāo)準(zhǔn),但新一代算法 Brotli(由 Google 開發(fā))在壓縮率上更勝一籌。

算法壓縮率CPU 開銷瀏覽器支持Nginx 支持
gzip70~80%? 所有? 內(nèi)置
brotli80~90%? 現(xiàn)代瀏覽器? 需編譯模塊

如何在 Nginx 中啟用 Brotli?

編譯 Nginx 時加入 --add-module=../ngx_brotli(需提前下載模塊)

或使用預(yù)編譯包(如 Ubuntu 22.04+ 的 nginx-extras)

brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype;
brotli_min_length 1024;
brotli_vary on;

壓縮率實測對比(相同 JS 文件)

文件原始大小gzip 壓縮后brotli 壓縮后
bundle.js210KB42KB35KB

節(jié)省了 7KB,相當(dāng)于 17% 的額外壓縮率。

建議:如果你的用戶群體以現(xiàn)代瀏覽器為主(Chrome 90+, Firefox 85+, Safari 14+),建議同時啟用 gzip 和 brotli,Nginx 會根據(jù) Accept-Encoding 自動選擇最優(yōu)算法。

gzip on;
gzip_types ...;

brotli on;
brotli_types ...;

# Nginx 會按順序匹配:br > gzip > 無壓縮

瀏覽器優(yōu)先請求 br,Nginx 返回 Brotli;不支持則回退到 gzip。

性能壓測:壓縮帶來的 QPS 提升

我們使用 wrk 工具對同一接口進行壓測:

無壓縮場景

wrk -t4 -c100 -d30s http://localhost/api/users

結(jié)果:

Running 30s test @ http://localhost/api/users
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    12.45ms   15.23ms 225.00ms   88.90%
    Req/Sec     820.75    140.52   1.15k    74.00%
  98490 requests in 30.02s, 14.86MB read
Requests/sec:   3281.23
Transfer/sec:    508.24KB

啟用 gzip 后

wrk -t4 -c100 -d30s http://localhost/api/users

結(jié)果:

Running 30s test @ http://localhost/api/users
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     8.12ms    9.87ms 180.00ms   91.20%
    Req/Sec    1250.65    180.40   1.80k    78.00%
  150080 requests in 30.01s, 3.74MB read
Requests/sec:   5001.33
Transfer/sec:    124.65KB

對比分析

指標(biāo)無壓縮gzip 壓縮提升
QPS3,2815,00152%
帶寬消耗508KB/s124KB/s75%
平均延遲12.45ms8.12ms35%

壓縮不僅提升用戶體驗,還顯著提升服務(wù)器吞吐量!在高并發(fā)場景下,這意味著你可以在相同硬件下支持更多用戶。

安全與合規(guī)建議

1. 避免壓縮敏感數(shù)據(jù)

雖然 gzip 本身不泄露數(shù)據(jù),但歷史上曾出現(xiàn) CRIMEBREACH 攻擊,利用壓縮率差異推斷 HTTPS 中的 CSRF Token。

解決方案

  • 不壓縮包含敏感信息的響應(yīng)(如 /api/user/profile 包含 token)
  • 在 Nginx 中排除特定路徑:
location ~ ^/api/user/ {
    gzip off;
    proxy_pass http://localhost:8080;
}

2. 避免壓縮 HTML 中的動態(tài) Token

如果你的 HTML 模板中包含:

<script>
  window.CSRF_TOKEN = "abc123xyz";
</script>

那么每次請求的 HTML 內(nèi)容都不同,壓縮率不穩(wěn)定,可能被攻擊者利用。

建議:將 Token 放入獨立 API(如 /api/csrf),不壓縮 HTML 模板。

3. 遵守 GDPR / CCPA

壓縮本身不涉及數(shù)據(jù)處理,但如果你壓縮的是用戶隱私數(shù)據(jù)(如個人資料、訂單),請確保:

  • 傳輸全程 HTTPS
  • 日志中不記錄響應(yīng)體
  • 有數(shù)據(jù)保留策略

監(jiān)控與告警:如何自動化檢測壓縮狀態(tài)?

在生產(chǎn)環(huán)境中,我們不能依賴人工檢查。建議接入監(jiān)控系統(tǒng)。

使用 Prometheus + Nginx Exporter

安裝 nginx-prometheus-exporter(開源工具)

配置 Nginx 開啟 stub_status

location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
}

部署 exporter,它會采集 nginx_http_gzip_ratio 指標(biāo)。

Grafana 面板示例(偽代碼)

告警規(guī)則:若某接口壓縮率持續(xù)低于 60%,說明 gzip_types 可能遺漏了 MIME 類型,需人工介入。

Shell 腳本每日檢查(可加入 crontab)

#!/bin/bash
URL="http://your-domain.com/api/ping"
RESULT=$(curl -s -H "Accept-Encoding: gzip" -o /dev/null -w "%{http_code}:%{size_download}" $URL)

CODE=${RESULT%:*}
SIZE=${RESULT#*:}

if [ "$CODE" != "200" ]; then
  echo "? HTTP Error: $CODE"
  exit 1
fi

if [ "$SIZE" -gt 5000 ]; then
  echo "??  API response too large: $SIZE bytes (expected <5KB)"
  echo "?? Check if gzip is enabled for application/json"
  exit 1
fi

echo "? Gzip OK: $SIZE bytes"

與現(xiàn)代前端構(gòu)建工具的協(xié)同

如今,前端工程化工具(如 Webpack、Vite、esbuild)已經(jīng)支持壓縮輸出。

問題:Nginx 壓縮 vs 前端預(yù)壓縮?

方案優(yōu)點缺點
前端預(yù)壓縮(.js.gz)無 CPU 開銷;響應(yīng)極快需要構(gòu)建時生成 .gz 文件;部署復(fù)雜;不支持動態(tài)內(nèi)容
Nginx 動態(tài)壓縮配置簡單;自動適配;支持動態(tài)內(nèi)容每次請求有輕微 CPU 開銷

推薦策略:雙軌制

location ~* \.(js|css|json|xml)$ {
    # 先嘗試讀取 .gz 文件(預(yù)壓縮)
    gzip_static on;
    # 若無 .gz 文件,則動態(tài)壓縮
    gzip on;
    gzip_types application/javascript text/css application/json application/xml;
    add_header Content-Encoding gzip;
}

其中:

  • gzip_static on;:Nginx 優(yōu)先查找同名 .gz 文件,如 app.js.gz
  • 若存在,直接返回,無需壓縮
  • 若不存在,啟用動態(tài)壓縮

最佳實踐:CI/CD 流程中,構(gòu)建時自動生成 .js.gz、.css.gz,部署時一同上傳。Nginx 自動優(yōu)先使用。

示例:Vite 構(gòu)建后生成 .gz 文件

# package.json
{
  "scripts": {
    "build": "vite build && gzip -k -9 dist/assets/*.js dist/assets/*.css"
  }
}

構(gòu)建后目錄:

dist/
├── assets/
│   ├── app.js
│   ├── app.js.gz ← 自動生成
│   ├── style.css
│   └── style.css.gz

Nginx 配置:

location ~* \.(js|css|json|xml)$ {
    gzip_static on;   # 優(yōu)先使用 .gz
    gzip on;          # 備用:動態(tài)壓縮
    gzip_types application/javascript text/css application/json application/xml;
    expires 1y;
    add_header Cache-Control "public, immutable";
}

效果:99% 的請求命中預(yù)壓縮文件,0 CPU 開銷;1% 的新資源(如動態(tài)生成的 JSON)走動態(tài)壓縮,平衡完美。

與 HTTP/2 和 HTTP/3 的關(guān)系

HTTP/2 和 HTTP/3 本身支持多路復(fù)用、頭部壓縮(HPACK/QPACK),但不替代 gzip。

為什么?

  • HPACK 只壓縮 HTTP 頭部(如 User-Agent, Cookie),不壓縮響應(yīng)體
  • gzip 壓縮的是響應(yīng)內(nèi)容(body)

所以,即使使用 HTTP/2,你仍然需要 gzip。

最佳組合:HTTP/2 + gzipHTTP/3 + brotli

測試你的協(xié)議版本

curl -I --http2-prior-knowledge https://your-site.com/api/users

總結(jié):Nginx gzip 配置最佳實踐清單

項目推薦配置
啟用 gzipgzip on;
壓縮級別gzip_comp_level 6;
最小長度gzip_min_length 1024;
壓縮類型gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype;
代理壓縮gzip_proxied any;
Vary 頭gzip_vary on;
緩沖區(qū)gzip_buffers 16 8k;
HTTP 版本gzip_http_version 1.1;
禁用舊瀏覽器gzip_disable "MSIE [1-6]\.";
靜態(tài)資源優(yōu)化gzip_static on; + 構(gòu)建時生成 .gz 文件
高級優(yōu)化啟用 Brotli(現(xiàn)代瀏覽器)
監(jiān)控日志記錄 $gzip_ratio + Prometheus 告警
安全不壓縮含 Token 的 HTML/JSON

結(jié)語:壓縮不是終點,而是起點 

啟用 gzip,只是性能優(yōu)化的第一步。真正的高性能網(wǎng)站,還需要:

  • CDN 分發(fā)
  • 緩存策略(Cache-Control, ETag)
  • 圖片懶加載與 WebP 格式
  • 資源預(yù)加載(preload/prefetch)
  • 代碼分割(Code Splitting)
  • 服務(wù)端渲染(SSR)或靜態(tài)站點生成(SSG)

但請記?。?strong>每一個 1% 的加載時間節(jié)省,都是對用戶耐心的尊重。

當(dāng)你在深夜收到“用戶反饋頁面卡頓”的告警時,回溯到 gzip 配置,發(fā)現(xiàn)它被注釋了 —— 那一刻,你會感謝今天寫下這篇配置的自己。

 “Optimization is not about doing things faster. It’s about doing fewer things.” —— Anonymous

附錄:完整 Nginx 配置模板(可直接復(fù)制)

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$gzip_ratio"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;
    types_hash_max_size 2048;

    # ========== GZIP CONFIG ==========
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/vnd.ms-fontobject font/opentype;
    gzip_proxied any;
    gzip_vary on;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_disable "MSIE [1-6]\.";

    # ========== STATIC ASSETS ==========
    gzip_static on;

    # ========== SERVER ==========
    server {
        listen 80;
        server_name localhost;

        location /static/ {
            root /var/www/my-app;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        location /api/ {
            proxy_pass http://localhost:8080;
            proxy_http_version 1.1;
            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_set_header X-Forwarded-Proto $scheme;
        }

        location / {
            proxy_pass http://localhost:8080;
            proxy_http_version 1.1;
            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_set_header X-Forwarded-Proto $scheme;
        }
    }
}

以上就是Nginx使用gzip模塊壓縮靜態(tài)資源的基礎(chǔ)配置與啟用的詳細(xì)內(nèi)容,更多關(guān)于Nginx gzip壓縮靜態(tài)資源的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Nginx響應(yīng)頭Vary介紹與應(yīng)用小結(jié)

    Nginx響應(yīng)頭Vary介紹與應(yīng)用小結(jié)

    響應(yīng)頭部字段在控制緩存行為、優(yōu)化性能等方面起著重要作用,Vary頭部字段是其中一個關(guān)鍵字段,它用于指示緩存代理在何種條件下緩存響應(yīng),下面就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2025-09-09
  • Nginx解決前端訪問資源跨域問題的方法詳解

    Nginx解決前端訪問資源跨域問題的方法詳解

    這篇文章主要給大家介紹了關(guān)于Nginx解決前端訪問資源跨域問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 如何通過nginx解決跨域問題

    如何通過nginx解決跨域問題

    文章描述了在使用Nginx版本1.29.1配置代理時遇到的跨域問題,由于響應(yīng)中缺少Access-Control-Allow-Origin頭部,導(dǎo)致從10.20.4.1訪問10.20.4.2:5000時出現(xiàn)跨域錯誤,通過配置Nginx以添加該頭部,問題得到了解決,感興趣的朋友跟隨小編一起看看吧
    2026-05-05
  • 基于Nginx實現(xiàn)HTTPS網(wǎng)站設(shè)置的步驟

    基于Nginx實現(xiàn)HTTPS網(wǎng)站設(shè)置的步驟

    本文主要介紹了Nginx實現(xiàn)HTTPS網(wǎng)站設(shè)置的步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • CentOS 6.7下nginx SSL證書部署的方法

    CentOS 6.7下nginx SSL證書部署的方法

    這篇文章主要介紹了在CentOS 6.7下nginx SSL證書部署的方法,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • Nginx常用配置以及代理轉(zhuǎn)發(fā)操作詳解

    Nginx常用配置以及代理轉(zhuǎn)發(fā)操作詳解

    這篇文章主要給大家介紹了關(guān)于Nginx常用配置以及代理轉(zhuǎn)發(fā)的相關(guān)資料,nginx一般被用來做反向代理,將請求轉(zhuǎn)發(fā)到應(yīng)用服務(wù)器上,比如tomcat的應(yīng)用,需要的朋友可以參考下
    2023-09-09
  • nginx配置gzip壓縮頁面

    nginx配置gzip壓縮頁面

    gzip(GNU-ZIP)是一種壓縮技術(shù)。經(jīng)過gzip壓縮后頁面大小可以變?yōu)樵瓉淼?0%甚至更小,這樣,用戶瀏覽頁面的時候速度會塊得多,下面看一下Nginx配置Gzip的方法
    2013-12-12
  • Ubuntu系統(tǒng)下安裝與完全卸載Nginx的步驟

    Ubuntu系統(tǒng)下安裝與完全卸載Nginx的步驟

    在Linux服務(wù)器上管理和部署Web服務(wù),Nginx是一個常見的選擇,因為它的高性能和穩(wěn)定性,這篇文章主要介紹了Ubuntu系統(tǒng)下安裝與完全卸載Nginx的相關(guān)資料,需要的朋友可以參考下
    2025-08-08
  • Nginx防止惡意域名解析過程

    Nginx防止惡意域名解析過程

    Nginx防止惡意域名解析,通過編輯nginx.conf文件添加限制配置,確保網(wǎng)站安全合規(guī),避免服務(wù)器IP被關(guān)閉處理
    2026-05-05
  • Nginx配置多端口多域名訪問的實現(xiàn)

    Nginx配置多端口多域名訪問的實現(xiàn)

    這篇文章主要介紹了Nginx配置多端口多域名訪問的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評論

吴旗县| 平塘县| 巴中市| 安溪县| 湟源县| 黑龙江省| 连城县| 蓬溪县| 神木县| 新兴县| 那坡县| 无棣县| 永嘉县| 武清区| 盐源县| 梁山县| 新源县| 韶山市| 廊坊市| 会同县| 肇源县| 米易县| 调兵山市| 宝兴县| 鄂托克前旗| 古丈县| 化隆| 武穴市| 鄂温| 牙克石市| 汨罗市| 兰州市| 新晃| 读书| 勃利县| 正阳县| 神农架林区| 甘孜| 青龙| 福清市| 巫山县|