一個 HTTP request 從瀏覽器出發,依序經過 DNS 解析、TLS 加密、CDN/WAF 邊緣層、Load Balancer、API Gateway(認證與限流)、Application 處理、Cache/Database 資料層,最後回傳 Response。但大部分 request 不會走完全程——靜態檔在 CDN 就回了,沒 token 的在 Gateway 就被擋了。
你在瀏覽器按下 Enter 的那一瞬間,觸發了這整條鏈。這篇把所有路徑畫出來,每一層指向對應的深入文章。
Level 0:全景圖
flowchart LR B[Browser] --> N[Network] N --> E[Edge] E --> LB[Load Balancer] LB --> GW[Gateway] GW --> APP[Application] APP --> DATA[Data Layer] DATA --> RES[Response] style B fill:#e3f2fd,stroke:#1976d2 style N fill:#e3f2fd,stroke:#1976d2 style E fill:#f3e5f5,stroke:#8e24aa style LB fill:#f3e5f5,stroke:#8e24aa style GW fill:#ede7f6,stroke:#5e35b1 style APP fill:#e8f5e9,stroke:#388e3c style DATA fill:#fff3e0,stroke:#f57c00 style RES fill:#e0f7fa,stroke:#00838f
Request 依序通過 Browser → Network → Edge → Load Balancer → Gateway → Application → Data Layer → Response 七個階段,但每一層都有「提前結束」的分支。
看起來很線性?往下看每一層的展開——你會發現大部分 request 根本走不到最右邊。
Level 1:Network 層
flowchart TD B[Browser] --> DNS{DNS Cache?} DNS -->|HIT| SKIP[跳過解析] DNS -->|MISS| RESOLVE[DNS 解析] RESOLVE --> IP[取得 IP] SKIP --> TLS[TLS Handshake] IP --> TLS TLS --> CONN[建立連線] style B fill:#e3f2fd,stroke:#1976d2 style DNS fill:#e3f2fd,stroke:#1976d2 style TLS fill:#e3f2fd,stroke:#1976d2
Browser 先查 DNS cache,miss 則解析 domain 取得 IP,接著做 TLS handshake 建立加密連線。
瀏覽器拿到 URL 後,第一件事是問「這個 domain 的 IP 是什麼」。如果本機 DNS cache 有就跳過,沒有就一路問到 authoritative DNS server。拿到 IP 之後做 TLS handshake 建立加密連線。
DNS 解析 — 大部分人忽略的第一步,但 TTL 設錯會讓你的服務切換卡好幾小時。 → Network & DNS:TTL 策略、DNS 命名規則、網段切分 → Route 53:AWS 的 DNS 服務、路由策略
TLS 加密 — 所有流量都該走 HTTPS。TLS 有 5-7% 的效能損耗,但這是必要成本。 → Reverse Proxy + TLS:Nginx TLS 設定、安全 header、HSTS → ACM:AWS 的免費 TLS 憑證
Level 1:Edge 層(CDN + WAF)
flowchart TD REQ[Request 到達 Edge] --> CDN{CDN Cache?} CDN -->|HIT| RES_CDN[直接回應 ✅] CDN -->|MISS| WAF{WAF / 防火牆} WAF -->|BLOCKED| ERR403[403 Forbidden ❌] WAF -->|PASS| NEXT[進入 Load Balancer] style REQ fill:#f3e5f5,stroke:#8e24aa style CDN fill:#f3e5f5,stroke:#8e24aa style RES_CDN fill:#e0f7fa,stroke:#00838f style ERR403 fill:#fce4ec,stroke:#c62828 style WAF fill:#f3e5f5,stroke:#8e24aa
靜態資源在 CDN cache hit 時直接回應,不到 server。通過 CDN 的 request 再經 WAF 過濾惡意請求。
這是第一個分支點。 靜態資源(CSS、JS、圖片)通常在 CDN 就被回應了——你的 server 根本不知道這個 request 存在過。
CDN — 把內容快取到離使用者最近的邊緣節點。Cache-Control header 決定快取多久。 → DNS、LB 與 CDN:Cloudflare CDN 設定 → CloudFront:AWS 的 CDN 服務 → ⚠️ 待寫:CDN 深入篇(Cache-Control 策略、邊緣計算、cache invalidation)
WAF / 防火牆 — 擋掉惡意請求(SQL injection、XSS、DDoS)。在 request 到達你的 app 之前就過濾。 → GuardDuty:AWS 的安全服務 → Application Security:OWASP Top 10 → ⚠️ 待寫:自架防火牆(iptables / nftables / fail2ban)
Level 1:Load Balancer
flowchart TD REQ[Request 通過 Edge] --> LB{Load Balancer} LB --> S1[Server 1] LB --> S2[Server 2] LB --> S3[Server 3] LB --> HC{Health Check} HC -->|Unhealthy| REMOVE[移除節點] style LB fill:#f3e5f5,stroke:#8e24aa style HC fill:#fce4ec,stroke:#c62828
Load Balancer 將 request 分配到多台 server,Health Check 確保不會送到已掛的節點。
Load Balancer 決定這個 request 交給哪台 server 處理。L4 看 IP/Port,L7 看 HTTP header/path。Health check 確保不會把流量送到已經掛掉的 server。
L4/L7 負載均衡 — 水平擴展的基礎。2 台 server 比 1 台快 53%,但 4 台不會比 2 台更好——瓶頸會轉移到 DB。 → 負載均衡:Nginx upstream、health check → NLB:AWS 的 L4/L7 LB → 水平擴展的天花板:壓測數據,2 台 +53%、4 台卡 DB → K8s Service:K8s 內建的服務發現與負載均衡
Level 1:Gateway 層(Ingress + API Gateway)
flowchart TD REQ[Request 到達 Gateway] --> AUTH{認證?} AUTH -->|FAIL| ERR401[401 Unauthorized ❌] AUTH -->|PASS| RATE{Rate Limit?} RATE -->|EXCEEDED| ERR429[429 Too Many ❌] RATE -->|OK| ROUTE[路由到對應服務] style REQ fill:#ede7f6,stroke:#5e35b1 style AUTH fill:#ede7f6,stroke:#5e35b1 style RATE fill:#ede7f6,stroke:#5e35b1 style ERR401 fill:#fce4ec,stroke:#c62828 style ERR429 fill:#fce4ec,stroke:#c62828
沒有帶 token 的 request 回傳 401,超過頻率限制的回傳 429。只有通過認證和限流的 request 進入 Application。
第二個分支點。 沒有帶 token 的 request 在這裡就被擋了。超過頻率限制的也是。只有通過認證 + 限流的 request 才會到你的 app。
API Gateway — 統一入口,處理認證、限流、路由、版本管理。 → API Gateway & Routing:Kong DB-less 設定 → K8s Ingress:Ingress Controller + cert-manager
CORS Preflight — 瀏覽器跨域請求會先發 OPTIONS,通常在 Gateway 或 Reverse Proxy 回應。 → Reverse Proxy:CORS header 設定
認證與授權 — JWT、OAuth、API Key,不同場景用不同方案。 → Identity & Access:RBAC/ABAC、零信任 → OAuth 指南:Authorization Code Flow
Level 1:Application 層
flowchart TD REQ[Request 到達 App] --> TYPE{請求類型} TYPE -->|GET + Cache| CACHE[查 Cache] TYPE -->|POST/PUT| DB_WRITE[寫 DB] TYPE -->|WebSocket| WS[建立長連線] TYPE -->|背景任務| QUEUE[丟進 Queue] CACHE -->|HIT| RES_CACHE[Cache 回應 ✅] CACHE -->|MISS| DB_READ[讀 DB] DB_WRITE --> QUEUE_ASYNC[非同步通知] QUEUE --> WORKER[Background Worker] style REQ fill:#e8f5e9,stroke:#388e3c style TYPE fill:#e8f5e9,stroke:#388e3c style RES_CACHE fill:#e0f7fa,stroke:#00838f style CACHE fill:#fff3e0,stroke:#f57c00 style DB_WRITE fill:#fff3e0,stroke:#f57c00 style DB_READ fill:#fff3e0,stroke:#f57c00 style QUEUE fill:#fff3e0,stroke:#f57c00
GET 請求先查 Cache,POST 直接寫 DB。WebSocket 建立長連線,背景任務丟進 Queue 由 Worker 處理。
這是最複雜的分支點。 不同類型的 request 走完全不同的路:
- GET(有 Cache)→ 先問 Redis,有就回,沒有才問 DB
- POST/PUT(寫入)→ 直接寫 DB,可能順便丟 Queue 做非同步處理
- WebSocket → 建立長連線,不是 request-response 模式
- 背景任務 → 丟進 Message Queue,Worker 慢慢處理
App 執行環境 — Container 裡跑,K8s 或 Docker Compose 管理。 → Container Runtime:Docker、namespace/cgroup → K8s Workloads:Deployment、StatefulSet、Job → 微服務壓測系列:9 個框架的效能比較
WebSocket — 即時通訊、推播通知、協作編輯。 → WebSocket:心跳機制、指數退避、多節點擴展
Level 1:Data 層
flowchart TD APP[Application] --> CACHE[(Redis Cache)] APP --> DB[(PostgreSQL)] APP --> STORAGE[(Object Storage)] APP --> QUEUE[Message Queue] CACHE -->|HIT| RES[Response ✅] CACHE -->|MISS| DB DB --> REPLICA[(Read Replica)] DB --> POOL[Connection Pool] QUEUE --> WORKER[Background Worker] WORKER --> DB WORKER --> STORAGE style CACHE fill:#fff3e0,stroke:#f57c00 style DB fill:#fff3e0,stroke:#f57c00 style STORAGE fill:#fff3e0,stroke:#f57c00 style QUEUE fill:#fff3e0,stroke:#f57c00 style RES fill:#e0f7fa,stroke:#00838f
Application 通常同時使用 Cache + DB + Storage + Queue,不是選一個。Cache hit 直接回應,miss 才查 DB。
Data 層不是「選一個」——大部分系統同時用 Cache + DB + Storage + Queue。 每個解決不同的問題。
Cache(Redis) — 讀多寫少的場景,Cache-aside 模式能提升 6.5 倍。 → Cache 的正確用法:mutex lock 防 stampede、delete not update → ElastiCache:AWS 的 Redis 託管服務
Database(PostgreSQL) — 交易型資料的唯一正解。連線池是最容易忽略的瓶頸。 → PostgreSQL:PgBouncer、備份還原 → PG Advanced:EXPLAIN、Partition、Vacuum → Database Landscape:選型決策框架 → 資料庫系列:12 篇深入 → RDS:AWS 的 DB 託管 → 連線池與擴展:pool=5 vs pool=50 的差異 → 讀寫分離:Read Replica 的實作
Object Storage(S3/MinIO) — 檔案、圖片、備份。不是 DB,是大型二進位物件的家。 → MinIO:物件儲存、Bucket 分層 → EFS:AWS 的三種儲存 → K8s Storage:PV/PVC/StorageClass
Message Queue — 非同步處理的橋樑。發 email、更新統計、通知下游,不需要讓使用者等。 → Event-driven & Queue:Outbox pattern、DLQ、技術選型 → EventBridge:AWS 的事件驅動
Level 1:Observability 層(貫穿所有層)
flowchart LR M[Metrics] --- L[Logs] --- T[Tracing] --- A[Alerts] style M fill:#fce4ec,stroke:#c62828 style L fill:#fce4ec,stroke:#c62828 style T fill:#fce4ec,stroke:#c62828 style A fill:#fce4ec,stroke:#c62828
Metrics、Logs、Tracing、Alerts 橫跨所有層,不是某一層的專屬。
Observability 不是某一層——它橫跨所有層。每一層都在產生 metrics、logs、traces。
Metrics — 量化系統健康度:RPS、latency、error rate、CPU/Memory。 → Prometheus + Grafana → K8s 監控:Prometheus Operator → CloudWatch
Logs — 當 metrics 告訴你「出事了」,logs 告訴你「出了什麼事」。 → ELK → CloudWatch Logs
Tracing — 一個 request 跨了 5 個服務,哪個服務最慢? → ⚠️ 待寫:Distributed Tracing 獨立篇(OpenTelemetry、Jaeger) → X-Ray:AWS 的 tracing 服務
Alerts — 不要等使用者回報問題,系統要自己喊痛。 → Alerts & ChatOps:告警分級、Runbook → Webhook 整合
Level 2:按請求類型的路徑比較
| 請求類型 | 完整路徑 | 到達哪裡 | 相關文章 |
|---|---|---|---|
| 靜態檔(CSS/JS/圖片) | Browser → CDN → Response | CDN 回應,不到 server | 29-dns-loadbalancing-cdn |
| API GET(有 cache) | → Gateway → App → Redis → Response | 不到 DB | 33-cache-correct-usage |
| API GET(cache miss) | → Gateway → App → Redis miss → DB → Response | 全程 | 11-database-postgresql |
| API POST(寫入) | → Gateway → App → DB + Queue | 不走 cache | 22-event-driven-queue |
| WebSocket | → Gateway → App(長連線) | 持久連線 | 23-websocket |
| 背景任務 | Queue → Worker → DB/Storage | 不經過 Gateway | 22-event-driven-queue |
| GraphQL | → Gateway → App → 多個 DB/Service | 一次打多個 | ⚠️ 待寫 |
| 301/302 Redirect | → 任一層 → Redirect → Browser 重新發 request | 重走一次 | 02-reverse-proxy-tls |
| CORS Preflight | → Gateway → OPTIONS response → 才發真正 request | 多一次來回 | 21-api-gateway |
知識缺口
這篇策展文串連了 30+ 篇文章,但有幾個層的深入內容還缺:
| 缺口 | 為什麼重要 | 建議放在哪 |
|---|---|---|
| ⚠️ CDN 深入篇 | Cache-Control 策略、邊緣計算、cache invalidation | infra/ 或 cloud/ |
| ⚠️ 自架防火牆 | iptables/nftables/fail2ban,不是所有人都用 AWS WAF | infra/ L6 |
| ⚠️ Distributed Tracing | 可觀測性三支柱缺一角,OpenTelemetry + Jaeger | infra/ L4 或 k8s/ |
| ⚠️ HTTP Response 優化 | 壓縮(gzip/brotli)、Cache-Control headers、ETag | infra/ 或 seo/ |
| ⚠️ GraphQL | 跟 REST 完全不同的 request 路徑 | backend/ 或 system-design/ |
| ⚠️ Circuit Breaker / Resilience | App 層超時或下游掛掉時的 fallback 路徑 | micro-service/ |
| ⚠️ Service Mesh (Istio/Linkerd) | 微服務間的 sidecar proxy、mTLS、流量管理 | k8s/ |
閱讀路徑
入門者
先看 Level 0 全景圖,理解「有這些層」就好。然後從 Network 層開始,一層一層往下讀。每層只讀第一個引用的文章。
有經驗的工程師
直接看 Level 2 的請求類型比較表,找到你最常處理的請求類型,然後深入那幾層。
架構師 / 面試準備
把整篇從頭到尾看一遍,特別注意每個分支點(CDN hit、WAF block、Cache hit、Auth fail)——面試最愛問「如果這一層掛了會怎樣」。
FAQ
Q: 一個 HTTP request 總共經過幾層? A: 完整路徑有 7 層:Network(DNS/TLS)→ Edge(CDN/WAF)→ Load Balancer → Gateway(Auth/Rate Limit)→ Application → Data(Cache/DB/Storage/Queue)→ Response。但大多數 request 會在中間某層提前結束。
Q: CDN cache 和 Redis cache 差在哪? A: CDN cache 在邊緣節點(離使用者最近),攔截靜態資源,request 不到你的 server。Redis cache 在 Application 層,攔截動態資料的讀取,request 不到 Database。兩者是不同層的快取,可以同時存在。
Q: 為什麼大部分 request 不會到 Database? A: 靜態檔被 CDN 回應、惡意請求被 WAF 擋掉、沒 token 被 Gateway 拒絕、讀取請求被 Redis Cache 命中——每一層都有「提前結束」的路徑,只有 Cache miss 的寫入/讀取請求才會真的打到 DB。
Q: Load Balancer L4 和 L7 怎麼選? A: L4 看 IP/Port,速度快但只能做簡單分流。L7 看 HTTP header/path,可以做 path-based routing 和 header-based routing。大部分 web 應用用 L7(Nginx / ALB),除非你需要極低延遲(遊戲/金融)才考慮 L4(NLB)。
Q: API Gateway 和 Reverse Proxy 差在哪? A: Reverse Proxy(Nginx)做 TLS 終結、負載均衡、靜態檔服務。API Gateway(Kong/AWS API Gateway)加上認證、限流、版本管理、請求轉換。小專案用 Nginx 就夠,微服務架構才需要獨立的 API Gateway。
Q: WebSocket 和一般 HTTP request 的路徑差在哪? A: 一般 HTTP 是 request-response 模式(打一次、回一次)。WebSocket 在 Gateway 層做 protocol upgrade 後建立持久連線,之後的資料雙向傳輸不經過完整的 request 流程。
延伸閱讀
- Infra 結論:按用戶規模的部署策略路線圖
- 免費午餐:不改程式碼效能翻倍的三個 infra 優化
- Infra 自架系列:33 篇,從 Network 到 K8s
- Kubernetes 實戰:8 篇,從 Workloads 到 GitOps
- AWS 雲端:12 篇,每篇映射回自架知識
- 瀏覽器發出 Request 後經歷了什麼:從瀏覽器渲染的角度看 request flow(前端視角)