升級策略:遷移到 HTTP/2 與 HTTP/3
了解了 HTTP/2 和 HTTP/3 的優勢後,本篇將介紹如何實際部署。從協定協商到伺服器配置,提供完整的升級指南。
一、 協定協商機制
1.1 ALPN(Application-Layer Protocol Negotiation)
ALPN 是 TLS 擴展,用於在握手時協商應用層協定:
協定標識:
| 標識 | 協定 |
|---|---|
h2 | HTTP/2 over TLS |
h2c | HTTP/2 明文(較少用) |
http/1.1 | HTTP/1.1 |
h3 | HTTP/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參數說明:
| 參數 | 說明 |
|---|---|
h3 | HTTP/3 協定 |
:443 | 埠號 |
ma | max-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.16.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 h26.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.18.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 沒生效
常見原因:
- 沒有 HTTPS(HTTP/2 需要 TLS)
- ALPN 沒配置
- 舊版瀏覽器
- 代理中間層降級
9.2 HTTP/3 沒生效
常見原因:
- 防火牆阻擋 UDP
- 沒有設置 Alt-Svc
- 瀏覽器停用(
chrome://flags) - 網路環境不支援
9.3 效能沒改善
可能原因:
- 資源數量少(HTTP/2 優勢不明顯)
- 舊優化造成反效果
- 伺服器配置不當
- 網路延遲高(握手優化效果有限)
總結
| 步驟 | HTTP/2 | HTTP/3 |
|---|---|---|
| 前提 | HTTPS + TLS 1.2+ | HTTPS + TLS 1.3 |
| Nginx | http2 指令 | quic + Alt-Svc |
| CDN | 通常預設開啟 | 需要手動啟用 |
| 驗證 | ALPN 協商 | Alt-Svc 檢查 |
| 回退 | 自動到 HTTP/1.1 | 自動到 HTTP/2 |
> **實務建議**:
- 使用 CDN 是最簡單的升級方式
- HTTP/2 幾乎沒有不升級的理由
- HTTP/3 需要考慮 UDP 支援情況
- 升級後記得移除舊的 HTTP/1.1 優化
進階挑戰
- 在本機配置 Nginx 支援 HTTP/2,使用自簽憑證測試。
- 使用 Caddy 部署一個自動支援 HTTP/3 的網站。
- 編寫監控腳本,追蹤網站的 HTTP 協定版本分佈。