跳至主要內容
Skip to content

升級策略:遷移到 HTTP/2 與 HTTP/3

了解了 HTTP/2 和 HTTP/3 的優勢後,本篇將介紹如何實際部署。從協定協商到伺服器配置,提供完整的升級指南。


一、 協定協商機制

1.1 ALPN(Application-Layer Protocol Negotiation)

ALPN 是 TLS 擴展,用於在握手時協商應用層協定:

協定標識

標識協定
h2HTTP/2 over TLS
h2cHTTP/2 明文(較少用)
http/1.1HTTP/1.1
h3HTTP/3(透過 Alt-Svc)

1.2 Alt-Svc(Alternative Services)

HTTP/3 使用 Alt-Svc 標頭公告支援:

http
HTTP/1.1 200 OK
Alt-Svc: h3=":443"; ma=86400, h3-29=":443"

HTTP/2 200
Alt-Svc: h3=":443"; ma=86400

參數說明

參數說明
h3HTTP/3 協定
:443埠號
mamax-age,快取秒數
persist是否跨網路保留

1.3 協定選擇流程


二、 Nginx 配置

2.1 HTTP/2 配置

nginx
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # TLS 配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # HTTP/2 優化
    http2_max_concurrent_streams 128;
    http2_push_preload on;  # 自動推送 Link preload

    location / {
        root /var/www/html;
    }
}

2.2 HTTP/3 配置(Nginx 1.25+)

nginx
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    listen 443 quic;
    listen [::]:443 quic;

    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # HTTP/3 需要 TLS 1.3
    ssl_protocols TLSv1.2 TLSv1.3;

    # 公告 HTTP/3 支援
    add_header Alt-Svc 'h3=":443"; ma=86400';

    location / {
        root /var/www/html;
    }
}

2.3 確認配置

bash
# 測試 HTTP/2
curl -I --http2 https://example.com

# 測試 HTTP/3
curl -I --http3 https://example.com

# 查看協定
curl -sI https://example.com | grep -i alt-svc

三、 Caddy 配置

Caddy 預設自動啟用 HTTP/2 和 HTTP/3:

3.1 基本配置

caddyfile
example.com {
    root * /var/www/html
    file_server
}

就這樣!Caddy 自動:

  • 申請 Let's Encrypt 憑證
  • 啟用 HTTP/2
  • 啟用 HTTP/3
  • 設置 Alt-Svc 標頭

3.2 進階配置

caddyfile
example.com {
    root * /var/www/html
    file_server

    # 自訂 TLS
    tls /path/to/cert.pem /path/to/key.pem

    # 可選:停用 HTTP/3
    servers {
        protocols h1 h2
    }
}

四、 Node.js 伺服器

4.1 HTTP/2 with Express

javascript
const express = require("express");
const http2 = require("http2");
const fs = require("fs");

const app = express();

app.get("/", (req, res) => {
  res.send("Hello HTTP/2!");
});

// HTTP/2 需要自己處理
const server = http2.createSecureServer(
  {
    key: fs.readFileSync("key.pem"),
    cert: fs.readFileSync("cert.pem"),
    allowHTTP1: true, // 回退支援
  },
  app
);

server.listen(443, () => {
  console.log("HTTP/2 server running on port 443");
});

4.2 HTTP/2 Server Push

javascript
const http2 = require("http2");
const fs = require("fs");

const server = http2.createSecureServer({
  key: fs.readFileSync("key.pem"),
  cert: fs.readFileSync("cert.pem"),
});

server.on("stream", (stream, headers) => {
  const path = headers[":path"];

  if (path === "/") {
    // 推送 CSS
    stream.pushStream({ ":path": "/style.css" }, (err, pushStream) => {
      pushStream.respond({ ":status": 200, "content-type": "text/css" });
      pushStream.end("body { color: blue; }");
    });

    // 回應 HTML
    stream.respond({ ":status": 200, "content-type": "text/html" });
    stream.end(
      '<html><link rel="stylesheet" href="/style.css"><body>Hello</body></html>'
    );
  }
});

server.listen(443);

五、 CDN 升級

使用 CDN 是最簡單的升級方式。

5.1 Cloudflare

控制台 → Speed → Optimization → Protocol Optimization
  ✅ HTTP/2
  ✅ HTTP/3 (with QUIC)

自動生效,無需修改程式碼。

5.2 AWS CloudFront

json
{
  "DistributionConfig": {
    "HttpVersion": "http2and3",
    "Origins": [...]
  }
}

5.3 Google Cloud CDN

預設支援 HTTP/2,HTTP/3 需要:

bash
gcloud compute backend-services update BACKEND_SERVICE \
    --enable-cdn \
    --protocol HTTP2

六、 驗證與監控

6.1 Chrome DevTools

Network 面板 → 右鍵欄位標題 → 勾選 Protocol

h2 = HTTP/2
h3 = HTTP/3
http/1.1 = HTTP/1.1

6.2 命令列工具

bash
# HTTP/2
curl -I --http2 -s https://example.com | head -1

# HTTP/3(需要 curl 7.66+)
curl -I --http3 -s https://example.com | head -1

# 詳細資訊
curl -v --http2 https://example.com 2>&1 | grep -i h2

6.3 線上工具

6.4 監控指標

指標說明工具
協定分佈h2/h3 比例Analytics
TTFB首位元組時間RUM
連線復用率連線效率Server logs
0-RTT 比例QUIC 優化效果QUIC logs

七、 升級前檢查清單

7.1 前提條件

  • [ ] 有效的 TLS 憑證
  • [ ] TLS 1.2+ 支援
  • [ ] 伺服器軟體支援(Nginx 1.9.5+, Apache 2.4.17+)
  • [ ] 防火牆允許 UDP 443(HTTP/3)

7.2 HTTP/1.1 優化移除

升級後,某些舊優化應該移除

舊優化HTTP/2+ 狀態說明
域名分片❌ 有害阻止連線復用
圖片精靈⚠️ 可能有害增加單一檔案大小
CSS/JS 合併⚠️ 視情況影響快取效率
內聯 CSS/JS⚠️ 視情況無法複用
Base64 圖片❌ 有害增大 HTML

7.3 新優化考慮

優化說明
資源提示<link rel="preload">
103 Early Hints預載資源
適當拆分細粒度快取
優先級控制Priority Hints

八、 回退策略

8.1 自動回退

現代瀏覽器會自動處理:

HTTP/3 失敗 → HTTP/2 → HTTP/1.1

8.2 伺服器端回退

nginx
# Nginx: 允許 HTTP/1.1 回退
server {
    listen 443 ssl http2;
    # HTTP/2 失敗時自動回退到 HTTP/1.1
}

8.3 監控回退

追蹤協定使用分佈,發現異常回退:

javascript
// 客戶端監控
if (performance.getEntriesByType) {
  const entries = performance.getEntriesByType("resource");
  entries.forEach((entry) => {
    console.log(entry.name, entry.nextHopProtocol);
    // "h2", "h3", "http/1.1"
  });
}

九、 常見問題

9.1 HTTP/2 沒生效

常見原因

  1. 沒有 HTTPS(HTTP/2 需要 TLS)
  2. ALPN 沒配置
  3. 舊版瀏覽器
  4. 代理中間層降級

9.2 HTTP/3 沒生效

常見原因

  1. 防火牆阻擋 UDP
  2. 沒有設置 Alt-Svc
  3. 瀏覽器停用(chrome://flags
  4. 網路環境不支援

9.3 效能沒改善

可能原因

  1. 資源數量少(HTTP/2 優勢不明顯)
  2. 舊優化造成反效果
  3. 伺服器配置不當
  4. 網路延遲高(握手優化效果有限)

總結

步驟HTTP/2HTTP/3
前提HTTPS + TLS 1.2+HTTPS + TLS 1.3
Nginxhttp2 指令quic + Alt-Svc
CDN通常預設開啟需要手動啟用
驗證ALPN 協商Alt-Svc 檢查
回退自動到 HTTP/1.1自動到 HTTP/2

> **實務建議**:

  1. 使用 CDN 是最簡單的升級方式
  2. HTTP/2 幾乎沒有不升級的理由
  3. HTTP/3 需要考慮 UDP 支援情況
  4. 升級後記得移除舊的 HTTP/1.1 優化

進階挑戰

  1. 在本機配置 Nginx 支援 HTTP/2,使用自簽憑證測試。
  2. 使用 Caddy 部署一個自動支援 HTTP/3 的網站。
  3. 編寫監控腳本,追蹤網站的 HTTP 協定版本分佈。

延伸閱讀與資源