Web App Architecture:一個 production web app 在雲上長什麼樣

Published on Updated on Written by

一個 production web app 在雲上從來不是「一個程式跑著」——是 N 個部分(DNS、CDN、load balancer、runtime、DB、object storage、queue、secrets、log/metric…)各司其職、接在一起。Architecture 就是這張拼圖:有哪些部分、每個在解什麼、什麼時候用 managed service、什麼時候自己 host。對一個人包辦整個 web app 的工程師(solo founder、接案者)來說,沒有 SRE / DevOps team 接你的後段——這頁是地圖。

Note

這不是 FAANG-style system design。 「設計 Twitter 怎麼 scale 到 1B users」、「cache stampede 怎麼處理」屬於另一個取向,目標讀者是準備 senior 面試的人。這頁的目標相反:把一個 web app(LLM wrapper、新聞站、接案專案)端到端送上線、每個部分夠用不壞,不需要撐百萬 QPS。

為什麼值得學

  • 一個人包辦整個 stack 的現實。 你一個人寫 code 也一個人接 page、接部署、接 secret rotation、接 backup 演練。看不懂這張地圖,等於把產品丟給雲端業者的預設值。
  • 這件事「一人 doable」其實是 2020 年代才成立。 Heroku 之後的 Vercel / Render / Fly / Cloudflare / Supabase / Neon 這波 managed service,把以前要 SRE team 才能搭的東西降到「裝幾個 SDK + 跑幾條 CLI」。看不懂這層 = 用不到這波紅利。
  • LLM agent 時代,你的角色變了。 agent 現在能 scaffold 整套 web app + 部署,但它的選擇(挑哪家、開哪些功能、有沒有設 alert、secret 放哪)——你看不看得懂、挑不挑得出問題,決定品質落在哪。「自己手刻每行」的紅利在收,「能評斷 agent 決定」的紅利在開——而評斷的尺就是這張地圖。

定位與脈絡

一句話:什麼是 web app architecture

N 個 piece 各司其職、接成一個能對外服務的 web app。 Architecture 是四件事:(1) 有哪些 piece、(2) 每個在解什麼問題、(3) 它們怎麼接、(4) 每個用 managed 還是自己 host。前三點是穩的、值得寫死;第四點隨雲端業者的產品 1–2 年洗一次牌——所以這頁不會幫你挑「2026 最該用哪家」,那段請丟給 agent 即時 survey。

一個請求的全旅程

從 user 在瀏覽器打 URL 到看到結果,中間會經過這些部分:

flowchart LR
  U[User browser] -->|DNS lookup| D[DNS]
  D --> CDN[CDN / edge cache]
  CDN -->|cache hit: static asset| U
  CDN -->|cache miss / dynamic| LB[Load balancer<br/>+ TLS + WAF]
  LB --> R[Application runtime<br/>server / serverless / edge]
  R --> DB[(Managed DB)]
  R --> OBJ[(Object storage)]
  R --> EXT[External APIs<br/>LLM / email / payments]
  R --> Q[Queue / pub-sub]
  Q --> W[Background worker]
  W --> DB
  W --> EXT
  R -.-> OBS[Logs / metrics / traces<br/>alerts]
  W -.-> OBS
  R -.-> SEC[Secrets store]
  W -.-> SEC

每一個都是一個角色,不是某一家雲端業者的特定產品。下面這份表格才開始把角色對到典型實作:

角色在解什麼典型 managed 選項
DNSdomain 翻譯成 IP / endpointCloudflare DNS、Route 53、Cloud DNS
CDN靜態(後來連動態 HTML 也是)資源快取到離 user 近的節點;擋 DDoSCloudflare、CloudFront、Fastly、Vercel
Load balancer / 反向代理流量分給多個 runtime instance;TLS termination、health check、WAFALB、Cloud Load Balancing;PaaS 通常內建
Application runtime你的 code 真正跑的地方——server、serverless、edge functionJS runtime;managed host:Render、Fly、Cloud Run、Vercel、AWS Lambda
Relational DB結構化資料、ACID transaction、查詢Supabase、Neon、RDS、Cloud SQL、PlanetScale
KV / cache高速 K-V、session、rate-limit counter、cache 層Upstash Redis、Cloudflare KV、Memorystore
Object storageuser upload、靜態檔、log archive、backupS3、Cloudflare R2、GCS
Queue / pub-sub「跑很久 / 可重試 / 多消費者」的工作從 request 路徑搬走SQS、Cloud Tasks、Cloudflare Queues、Inngest、Trigger.dev
Secrets storeAPI key / DB password / TLS cert——絕不能進 gitAWS Secrets Manager、Doppler、Vercel/Render 內建、Cloudflare secret binding
Observabilitylog、metric、trace;會響的 alertSentry、Better Stack、Axiom、Datadog;雲端業者內建
Auth註冊登入、session、權限Clerk、Auth0、Supabase Auth;或自架(passkey 之類)
Email / transactional 通訊註冊驗證、忘記密碼、收據、通知Resend、Postmark、SendGrid

權威的單篇骨幹解說是 Web Architecture 101(Jonathan Fulton,Datadog Staff Engineer / 前 Storyblocks SVP),用 Storyblocks 自家 production stack 把一個請求從 DNS 走到 DB 拆給你看;2017 寫的,serverless / edge 那段沒涵蓋,但骨架完全沒變,是非常少數能在 20 分鐘讀完、又不偏一家雲端業者的入門。

Managed vs self-host:solo dev 的預設

預設選 managed——除非有具體理由不選。理由:

  • 一個人的時間是常數。Self-host 一個 PostgreSQL 是永久背景任務——磁碟、備份、版本升級、replication、慢查詢分析全是你的,產品時間蒸發在這。
  • 主流 managed offering(Neon、Supabase、R2、SQS、Upstash…)pre-PMF 階段大多便宜到可以忽略。
  • 「lock-in」是真實但被誇大的問題——大多數 managed service 提供標準協定(Postgres wire protocol、S3 API),遷移痛但可行;產品還沒 PMF 之前就為 migration 設計是 premature optimization。

真的會推你去 self-host 的情境:法遵 / 資料主權要求(特定行業、特定地區)、月帳單破某個 threshold 且優化已盡、或者你有非常吃 query pattern 的場景——這時候你已經知道自己在幹嘛,不在這頁的目標讀者裡。

三種常見組合(不 prescribe 哪個對)

每組合是一個「抽象層次」的選擇,越上面 vendor 幫你做的越多:

組合例子適合代價
Full PaaSVercel + Supabase + R2 + Resend + InngestLLM wrapper、內容站、SaaS MVP抽象高、vendor 多、debug 時下層看不到、pricing 不透明
中庸 PaaSRender / Fly.io + Neon + R2 + 自跑 worker想看到下層、不想完全自架部署 / scaling 自己要懂多一點
Cloudflare-firstWorkers + D1 / R2 / Queues / Durable Objects全 edge、low-latency、便宜runtime 限制(沒 fs、wall time 上限、長任務不適合,見 JS runtime
IaaS 雲原生AWS(ECS / RDS / S3 / SQS / CloudFront)或 GCP 等價公司自己要 own、有 infra team、長期成本敏感學習曲線陡、IaC 必備、60% 時間花在雲端 console

雲端業者自家 reference 用作對照很有用:Cloudflare Reference Architecture: fullstack applications 一張圖把 12 個部分鋪好;GCP — 13 popular application architectures 把同一組部分鋪成 13 種不同形狀。但這兩份都會把每個部分指名成自家產品——把它們當「圖」用,不要當「lesson」用,概念該先從別處學到。

App code 那層也要配:Twelve-Factor

Architecture 不只是 infra 怎麼擺——你的 code 怎麼寫也要配合,不然 infra 給你的彈性用不到。The Twelve-Factor App(2011 年 Heroku 工程師寫的,到 2026 還是 cloud-native deploy 的事實上的標準)給了 12 條,幾個 solo dev 最常踩到、要硬記的:

  • Config in env——secret、DB URL、API key 都從環境變數讀,不要寫死進 code、也不要 commit 進 git。
  • Stateless processes——runtime instance 不能假設有「本機磁碟」存得住東西;上傳檔案進 object storage、session 進 DB / Redis,不然你 scale 不出去。
  • Backing services as attached resources——DB / Redis / queue 都用 URL 接,換實作不必改 code。
  • Dev/prod parity——dev 跑 SQLite、prod 跑 Postgres 等於在 prod 才 debug;用 Docker compose 把同樣的 DB 跑起來。

短、免費、過了十幾年還在被引——值得整篇看完。

Production-ready 跟「demo 跑得起來」差在哪

大多數 solo dev 漏的是這幾件——不是技術難度的問題,是「有沒有意識到要做」的問題:

  • Secrets 不准進 git:GitHub secret scanning 會抓到、但抓到的時候已經外流。用 secret store + CI / runtime 各自有 IAM 來讀。
  • 至少一條會響的 alert:接一個 Sentry / Better Stack / Axiom,並真的觸發一次確認它會響——不會響的 monitoring 是裝飾。
  • Backup 演練:managed DB 都有 backup,但「我能不能真的從昨天的 backup 救回來」要演練一次。沒演練過的 backup = 沒有 backup。
  • Rate limit / abuse mitigation:一張公開 API 端點被掃整晚足以打爆帳單。Cloudflare WAF / API Gateway / Redis-based limiter,挑一個有就行。
  • Staging 環境:跟 prod 同樣的 stack、獨立資源。「dev = staging」不算 staging。

幾個常見陷阱

  • K8s 太早:1–2 個 service 不該上 K8s。Cloud Run / Render / Fly 那層就夠,等你有 5+ services + 真的有 traffic 再說。
  • 自架求「省錢」:把 PostgreSQL 跑在 VM 上省 $20/月,結果半夜 disk full、backup 沒驗證、版本升級沒做,產品時間蒸發。Managed $20/月買的是不用想這些。
  • 單 region 等於沒設計:對全球 user 體驗差。要不要 multi-region 是預算題,但至少要知道你選了什麼——不是因為從沒想過所以變單 region。
  • 「serverless 一定便宜」迷思:高 QPS 場景 serverless 帳單會炸;long-running task 更不適合。Serverless 的勝場是「請求量不規律 + 不想管 server」,不是「永遠最便宜」。

怎麼入手

四段,順序有意義:讀骨幹 → 紙上設計 → 端到端上雲 → 批改 agent 的版本。每段一個獨立 session。

第 1 步:讀懂骨幹(一個 session)

骨幹概念穩、值得有意識地讀過一次。

👉 複製這段 prompt 開一個 session:

我想真正搞懂「一個 production web app 在雲上長什麼樣」——不是 FAANG-style
「設計 Twitter scale」那種 system design,而是「一個人從 0 把一個 web app
端到端送上線」的骨幹架構。請帶我做這件事,不確定就先問我:
1. 讓我自己先讀下面兩篇權威入門(請不要憑記憶複述、不要先總結,我讀完再來討論):
- Jonathan Fulton: Web Architecture 101
https://medium.com/storyblocks-engineering/web-architecture-101-a3224e126947
- The Twelve-Factor App
https://12factor.net/
如果你判斷還需要 1–2 個權威、不誤導、針對「solo dev / 接案 production stack」
(不是 interview prep、不是 enterprise SRE)的資源來補強,列出來並各附「為什麼可信」
一句話——作者要在 production cloud architecture 有 verifiable 的深度(實際 run
過 production web app、雲端業者官方架構文件、研討會講者之類),別給內容農場或 AI
拼湊的文章。
2. 我讀完後,用一段話跟我對齊重點:一個請求從 user 走到 DB 中間經過哪些部分
(DNS / CDN / LB / runtime / DB / object storage / queue / observability)、每個部分
在解什麼、為什麼一人團隊預設要選 managed、什麼情境才會自架,以及 12-factor 裡
最關鍵的幾條(config in env、stateless processes、backing services)為什麼跟
infra 形狀分不開。
3. 出幾題問我(為什麼要 CDN 不能直接讓 user 打 server、queue 解決的是哪種問題、
為什麼 secret 不能塞 .env 進 git、為什麼 backup 沒演練過等於沒有),我答完後依
官方文件或上面列的權威資源(不要憑你的記憶)幫我訂正。
若這個 session 過長、方向變過幾次,或你判斷 context 壓縮可能影響你的理解,提醒我:換新 session 通常會更穩、更準。提醒時一併把目前狀態、決策、待辦、關鍵檔案路徑整理成一份專案內的交接 Markdown 給下一輪 agent 用;沒有合適專案資料夾或任務很輕,就直接把摘要貼進新對話。不要頻繁提醒,只在真的會影響品質時提。

第 2 步:紙上設計一個情境(一個 session)

讀完骨幹後,把它套到一個具體情境——這一步是把概念落到「能討論」的形狀。先碰實作;先在紙上把架構畫出來、辯論該不該每個部分都有。

👉 複製這段 prompt 開一個 session:

我想透過「**設計**一個 web app 的架構」——不寫 code、只在紙上畫——把 production
web app 的骨幹內化。請帶我做:
1. 給情境:先問我要設計什麼(譬如 LLM wrapper SaaS、新聞站、接案專案…)以及關鍵
假設(預期流量級距、有沒有 user upload、要不要長任務、要不要全球低延遲、預算上限)。
2. 畫第一版(先不點名具體雲端業者產品):根據我給的情境,列出該有哪些部分(DNS / CDN /
runtime / DB / object storage / queue / secret / observability / auth / email…),
每個部分一句話說「為什麼這情境需要它」或「為什麼這情境不需要它」。
3. 落地到具體 stack:給我 2–3 種具體實作組合(譬如 Full PaaS、中庸 PaaS、Cloudflare-
first、AWS 雲原生),各自的取捨與大致 monthly cost。**請當下用 web search 查目前
的價格與可用性**,不要憑你的記憶——這類資訊每年都洗牌。
4. 出幾題問我(為什麼這情境該/不該上 edge runtime、為什麼長任務要進 queue、staging
環境要不要、災難復原該怎麼想),我答完後依雲端業者官方文件(不要憑你的記憶)幫我訂正。
若這個 session 過長、方向變過幾次,或你判斷 context 壓縮可能影響你的理解,提醒我:換新 session 通常會更穩、更準。提醒時一併把目前狀態、決策、待辦、關鍵檔案路徑整理成一份專案內的交接 Markdown 給下一輪 agent 用;沒有合適專案資料夾或任務很輕,就直接把摘要貼進新對話。不要頻繁提醒,只在真的會影響品質時提。

第 3 步:端到端送上雲(一個 session)

把上一步紙上的架構真的送上線——一個能跑、能被 user 打的小東西。這一步重點是摸到每個部分在實務上的接縫:DNS 要等多久才生效、TLS cert 是誰簽的、secret store 怎麼讓 runtime 讀到、log 跑到哪。

👉 複製這段 prompt 開一個 session:

我想透過真的把一個最小 web app 從 0 部署到 production——買 domain、接 TLS、接 CDN、
接 runtime、接 DB、接 object storage、接 secret store、接 log + alert——把骨幹從紙
上落到雲上。請帶我做:
1. 範圍:先一起把 POC scope 縮到「真的能跑、但不擴張」——譬如一個最小的 LLM wrapper:
user 上傳一張圖、call 一個 LLM API、回傳結果並存進 DB,有最簡登入。
2. 挑 stack 並動手:按情境推薦一組(請依當下情境推薦,不要憑你的記憶硬挑「最潮的」),
帶我把以下接齊,每接一個都說明它在解什麼:
- 自有 domain(買 / 接 DNS)
- TLS(managed cert)
- CDN
- runtime(server 或 serverless)跑 app
- managed DB(最常見是 Postgres)
- object storage 放 user upload
- secret store(不是 .env 進 git)
- log + 至少一條會響的 alert
3. 親手感受幾種失敗:
- 故意把 secret push 上 GitHub,看 GitHub secret scanning 怎麼反應
- 故意把 runtime 打到 OOM 或 timeout,看 alert 會不會真的響
- 從昨天的 DB backup 真的還原一次,看能不能救回來
讓我親眼看到「production-ready」差的是哪些設計,不是哪些動作。
4. 出幾題問我(為什麼 user upload 不直接寫進 DB、為什麼要 queue 不要 await、staging
環境的存在意義、cost 怎麼預估),我答完後依雲端業者官方文件(不要憑你的記憶)幫我訂正。
若這個 session 過長、方向變過幾次,或你判斷 context 壓縮可能影響你的理解,提醒我:換新 session 通常會更穩、更準。提醒時一併把目前狀態、決策、待辦、關鍵檔案路徑整理成一份專案內的交接 Markdown 給下一輪 agent 用;沒有合適專案資料夾或任務很輕,就直接把摘要貼進新對話。不要頻繁提醒,只在真的會影響品質時提。

第 4 步:批改 agent 給的 architecture(一個 session)

LLM agent 越來越會 scaffold 整套 web app;你的角色越來越是評斷它的選擇。練「看穿選擇」的肌肉——什麼是合理選擇、什麼是 agent 訓練資料的偏見、什麼是漏掉的——比親手刻每個部分更值錢。

👉 複製這段 prompt 開一個 session:

我想練「看穿一份 architecture 的決定」這件事——LLM agent 越來越會 scaffold 整套
web app,我的角色越來越是評斷它的選擇。請帶我做:
1. 出題給另一個 agent:用一個我給的情境,去跑另一個 agent(Claude Code / Cursor /
Vercel v0 / Bolt 之類),請它「設計並 scaffold 一個 production web app」。把它
生出來的 stack、配置、檔案結構帶回來。
2. 對齊 + 批改:你(這個 session 的 agent)跟我一起把它的選擇逐項過:
- 哪些部分它有放、哪些它略掉了(secret store?log?backup?rate limit?staging?)
- 它選的具體產品是不是吃了它訓練資料的偏見(譬如總推某一家)
- 哪些選擇對這情境是過度工程、哪些是不夠
- 有沒有 vendor lock-in 的隱形成本
- 12-factor 哪幾條被遵守、哪幾條被破
3. 重畫:根據批改結果,跟我一起把架構修正成更貼這情境的版本,並列出「如果我接受
agent 的版本不改,半年後最可能在哪個 piece 撞牆」。
4. 出幾題問我(為什麼 agent 預設選擇要批改、什麼樣的 stack 對「以後可能遷移」最
友善、哪些決定要錢進去之後才看得到),我答完後依雲端業者官方文件(不要憑你的記憶)
幫我訂正。
若這個 session 過長、方向變過幾次,或你判斷 context 壓縮可能影響你的理解,提醒我:換新 session 通常會更穩、更準。提醒時一併把目前狀態、決策、待辦、關鍵檔案路徑整理成一份專案內的交接 Markdown 給下一輪 agent 用;沒有合適專案資料夾或任務很輕,就直接把摘要貼進新對話。不要頻繁提醒,只在真的會影響品質時提。

延伸主題

這頁刻意走「廣不深」——把地圖鋪開。接下來深入哪一個部分,看你下個專案先撞到哪面牆——沒有單一「下一步」對所有讀者都對。