檔案上傳系統設計 (5) —— 邁向雲端架構
在前四篇中,我們從 HTTP 底層原理聊到本地儲存的優化與安全。但如果你的應用程式需要擴展(Scaling)——例如從一台 server 變成三台 server 做負載平衡——你會發現「本地儲存」會讓你陷入困境。
這原本是本系列的最後一篇,我們將跳出單機的限制,看看現代化的企業級架構是如何處理檔案的。
一、 本地儲存的痛點:Stateless (無狀態) 的重要性
在現代雲端架構中,我們要求應用伺服器(App Server)應該是 無狀態的 (Stateless)。
- 問題:如果你把圖片存在 Server A 的硬碟裡,當負載平衡器將下一個請求導向 Server B 時,Server B 的硬碟裡根本沒有那張圖,使用者就會看到破圖。
- 解法:檔案不應該存在 App Server,而應該存在一個「外部、集中式」的儲存空間。
二、 什麼是物件儲存 (Object Storage)?
不同於傳統的檔案系統(NAS/磁碟),AWS S3、Google Cloud Storage (GCS) 或 Azure Blob Storage 使用的是「物件儲存」邏輯。
- Bucket (儲存桶):就像是一個超大的根目錄。
- Key (鍵):就是檔案的路徑(例如
uploads/2025/me.jpg)。 - Object (物件):包含檔案內容與 Metadata。
為什麼要用它?
- 無限容量:你不需要擔心硬碟塞滿。
- 極高可靠性:雲端供應商會自動幫你做三份備份,幾乎不會遺失檔案。
- 靜態網站代管:它們可以直接透過 HTTP 協議讀取檔案,不需要經過你的 API。
三、 進階模式:預簽名 URL (Signed URL)
這是本篇最核心的知識點。很多新手會這樣寫: Browser -> Node.js Server -> AWS S3 SDK -> S3
這有一個巨大的缺點: 你的 Server 變成了一個「搬運工」。檔案先傳給 Server,Server 再傳給 S3。這會平白消耗你 Server 的雙倍流量(流量費很貴!)與 CPU 性能。
更強大的做法:預簽名上傳
- 申請通行證:前端告訴後端:「我要上傳檔案 A」。
- 簽發 URL:後端使用 S3 SDK 生成一個具有時效性的「預簽名 URL」(包含加密簽章),並回傳給前端。
- 直傳雲端:前端拿到 URL 後,直接用
PUT請求將檔案傳給 S3。
IMPORTANT
結果:你的 Server 只參與了「發門票」的幾毫秒,完全不參與大體積檔案的搬運工作。這能讓你的伺服器以極低負載撐起海量的上傳需求。
四、 CDN (內容傳遞網路) 加速
檔案存進雲端後,最後一哩路是「下載速度」。
如果你的 S3 Bucket 在美國,而使用者在台灣,載入圖片依然會很慢。這時你需要 CDN (如 CloudFront, Cloudflare):
- CDN 會在全球各地設有快取節點(Edge Location)。
- 使用者請求圖片時,會優先從「離他最近」的節點抓取快取。
- 這能大幅縮短延遲,讓網站達到「秒開」的效果。
總結
這五篇我們一起走過了:
- 底層原理:HTTP Multipart 與 Stream 概念。
- 儲存規劃:資料庫 Schema 與目錄結構。
- 安全防禦:Magic Number 與權限設定。
- 效能優化:壓縮、秒傳與斷點續傳。
- 雲端架構:S3、Signed URL 與 CDN。
檔案上傳看似簡單,但深挖下去全是後端工程的基礎功。希望這系列文章能幫你建立起系統化的知識體系。
️ 進階挑戰
嘗試使用 AWS S3 SDK (或任何 S3 相容服務) 生成一個預簽名 URL,並使用 curl 或是 Postman 成功將一張圖片上傳成功。
延伸閱讀與資源
- AWS Documentation: Using Presigned URLs
- Cloudflare: What is a CDN?