你是不是曾經看過 AWS 架構圖,然後心裡想:「為什麼要把東西分散在不同的 AZ(可用區)?這樣不是很麻煩嗎?」
或者你可能遇過這樣的情況:主管說要做「高可用架構」,但你不太確定這到底是什麼意思,更不知道該怎麼做。
別擔心,這篇文章就是要用最白話的方式,帶你搞懂這些問題:
核心概念解析
什麼是 AZ(Availability Zone)?
想像一下,你開了一家電商網站,所有伺服器都放在同一個機房裡。某天突然停電,或是機房淹水了,會發生什麼事?
沒錯,整個網站直接掛掉,所有客戶都無法下單,損失慘重。
這就是為什麼 AWS 設計了 AZ(Availability Zone,可用區) 的概念。
簡單來說:AZ 就是獨立的機房
每個 AZ 都是一個完全獨立的資料中心,就像是在不同地點開設的分店,各自有:
- 獨立的電力供應: 有自己的發電機和備用電源,不會互相影響
- 獨立的網路線路: 有自己的網路骨幹,一條線斷了不影響其他條
- 獨立的機房位置: 實體距離夠遠(通常數公里到數十公里),天災不會同時影響
- 獨特的名稱: 像
ap-northeast-1a、ap-northeast-1b、ap-northeast-1c(分別代表東京區域的三個機房)
最重要的特性:互不影響
假設 ap-northeast-1a 這個機房突然停電,甚至整個機房失火了(當然這種情況極少發生),部署在 ap-northeast-1b 和 ap-northeast-1c 的資源還是能正常運作,你的網站不會掛掉!
這就像是你在台北、台中、高雄都開了分店,台北店停電了,台中和高雄的店還是照常營業。
Public Subnet vs Private Subnet
知道了 AZ 是什麼之後,接下來要了解另一個重要概念:Subnet(子網路)。
先說個實際情境
你的網站需要一個「門面」讓客戶可以訪問,但你不希望把資料庫直接暴露在網路上讓任何人都能連線,對吧?這時候就需要區分「對外開放的區域」和「內部專用的區域」。
在 AWS 的 VPC(虛擬私有雲)架構中,Subnet 就是用來做這種區分的。
兩種 Subnet 的差別
| 類型 | 用途 | 能不能連外網? | 通常放什麼? |
|---|---|---|---|
| Public Subnet | 對外服務的「門面」 | ✅ 可以(有 Internet Gateway) | 負載平衡器 (ALB)、堡壘機 (Bastion Host) |
| Private Subnet | 內部核心服務的「後台」 | ❌ 不行(沒有 Internet Gateway) | 應用程式伺服器 (EC2)、資料庫 (RDS)、快取 (Redis) |
用餐廳來比喻:
- Public Subnet 就像餐廳的「外場」:客人可以進來點餐、用餐,服務生在這裡接待客人
- Private Subnet 就像餐廳的「廚房」:只有員工能進去,客人看不到也進不來,但這裡才是真正做菜的地方
為什麼要這樣設計?
- 安全性: 資料庫、應用程式邏輯放在 Private Subnet,駭客無法從網路直接攻擊
- 控制性: 所有對外的流量都必須經過 Public Subnet 的負載平衡器,方便管理和監控
- 最佳實踐: 這是業界公認的安全架構設計原則
為什麼要將 Subnet 分散到不同 AZ?
好,現在你已經知道:
- AZ 是獨立的機房,一個掛掉不會影響其他個
- Subnet 分成 Public(對外)和 Private(內部)兩種
接下來最重要的概念來了:
每個 AZ 都應該同時部署 Public Subnet 和 Private Subnet,形成一個完整的架構單元。
讓我用圖來說明:
graph TB
subgraph AZ-a["AZ-a (ap-northeast-1a)"]
PubA["Public Subnet<br/>10.0.1.0/24"]
ALB-A["ALB"]
PrivA["Private Subnet<br/>10.0.2.0/24"]
EC2-A["EC2 App"]
RDS-A["RDS 主要"]
PubA --> ALB-A
ALB-A --> PrivA
PrivA --> EC2-A
PrivA --> RDS-A
end
subgraph AZ-b["AZ-b (ap-northeast-1b)"]
PubB["Public Subnet<br/>10.0.3.0/24"]
ALB-B["ALB"]
PrivB["Private Subnet<br/>10.0.4.0/24"]
EC2-B["EC2 App"]
RDS-B["RDS 備用"]
PubB --> ALB-B
ALB-B --> PrivB
PrivB --> EC2-B
PrivB --> RDS-B
end
Internet["網際網路"] --> ALB-A
Internet --> ALB-B
style AZ-a fill:#e1f5ff
style AZ-b fill:#fff4e1
style Internet fill:#ffcccb為什麼要這樣設計?
每個 AZ 都是一個「獨立作戰單位」
想像你開了一家連鎖便利商店,你會怎麼設計分店?
❌ 錯誤做法:
- 店A 只有收銀台(Public Subnet)
- 店B 只有倉庫(Private Subnet)
- 客人要在店A結帳,然後商品從店B送過來
這樣的問題是:如果店A停電了,客人連結帳都不行。如果店B淹水了,所有分店都沒貨可賣。
✅ 正確做法:
- 每家分店都有收銀台(Public Subnet)
- 每家分店都有自己的倉庫(Private Subnet)
- 任何一家店出問題,其他店照常營業
AWS 的跨 AZ 架構就是這個概念!
每個 AZ 都部署完整的「Public + Private Subnet」組合,這樣任何一個 AZ 掛掉,其他 AZ 還能獨立運作。
具體來說有什麼好處?
好處 1:單一 AZ 故障不影響服務
情境: AZ-1a 整個機房停電了 ⚡
graph TB
Event["⚡ 故障發生:AZ-1a 停電"]
Event --> Path1["情況 1️⃣<br/>只有單一 AZ 架構"]
Event --> Path2["情況 2️⃣<br/>多個 AZ 架構"]
Path1 --> Check1{"能切換到<br/>其他 AZ 嗎?"}
Check1 -->|❌ 不能<br/>沒有其他 AZ| Fail["❌ 服務完全中斷<br/>所有資源都在 1a<br/>只能等 AWS 修復"]
Path2 --> Check2{"能切換到<br/>其他 AZ 嗎?"}
Check2 -->|✅ 能!<br/>有 AZ-1b 可用| Switch["🔄 自動切換"]
Switch --> Success["✅ 切換到 AZ-1b<br/>ALB → EC2 → RDS<br/>服務繼續運作"]
style Event fill:#ffd700,stroke:#ff6b6b,stroke-width:3px
style Path1 fill:#ffe6e6
style Path2 fill:#e6f7e6
style Check1 fill:#fff
style Check2 fill:#fff
style Fail fill:#ff9999,stroke:#ff0000,stroke-width:2px
style Switch fill:#fff9c4
style Success fill:#a5d6a7,stroke:#00aa00,stroke-width:2px核心差異就在:能不能切換!
- ❌ 單一 AZ → 無處可切 → 服務中斷
- ✅ 多 AZ → 自動切換 → 服務不中斷
這個切換是自動的! 你不需要半夜爬起來手動處理。
好處 2:流量可以均勻分散
當你在每個 AZ 都部署 Public + Private Subnet 後:
ALB 的智能分流:
- 使用者請求進來
- ALB 自動判斷哪個 AZ 比較不忙
- 把請求送到負載較低的 AZ 處理
- 同一個 AZ 內的 Public Subnet (ALB) 直接連到 Private Subnet (EC2),速度最快
好處:
- 沒有特定 AZ 會過載
- 同 AZ 內通訊更快(延遲更低)
- 系統整體效能更好
好處 3:維護時可以逐一升級,不用停機
假設你要更新應用程式:
單一 AZ 的做法:
1. 關閉服務
2. 更新程式
3. 重啟服務
→ 停機時間 30 分鐘,使用者無法使用多 AZ 的做法(滾動更新):
1. 先更新 AZ-a 的 EC2,ALB 把流量都送到 AZ-b
2. AZ-a 更新完成後,再更新 AZ-b,流量回到 AZ-a
3. 全程服務不中斷!
→ 零停機時間跨 AZ 資源如何相互溝通?
看到這裡,你應該已經理解為什麼要把資源分散到不同 AZ 了:當某個 AZ 掛掉時,其他 AZ 可以接手,服務就不會中斷。
聽起來很棒,對吧?
但是…你可能開始想:
「AZ-a 在東京某個機房,AZ-b 在另一個機房,它們距離可能有好幾公里遠。」
「那 AZ-a 的 ALB 要怎麼把請求送到 AZ-b 的 EC2?」
「而且 AZ-a 掛掉的時候,系統怎麼知道要切到 AZ-b?它們之間到底能不能溝通?」
這個問題超重要!因為如果不同 AZ 之間不能溝通,那前面講的「自動切換」根本不可能發生。
所以這一章,我們就來解答這個關鍵問題。
答案很簡單:可以通訊!
在同一個 VPC 裡,不同 AZ 的資源可以直接互相溝通,就像在同一個區域網路一樣!
是不是覺得有點神奇?讓我解釋給你聽。
為什麼不同 AZ 可以互通?
想像一下這個情境:
你的公司在台北、台中、高雄都有辦公室(就像不同的 AZ)。雖然辦公室在不同城市,但是:
- 每個辦公室都連到公司的內部網路(這就是 VPC)
- 台北的同事可以直接訪問台中辦公室的檔案伺服器
- 高雄的同事可以用公司內部 Email 跟台北的人溝通
AWS 的 AZ 就是這樣運作的!
技術上是怎麼做到的?
1. VPC 本身就是一個大內網
當你建立一個 VPC(例如 10.0.0.0/16),這個 IP 範圍內的所有資源都在「同一個網路」裡。
VPC: 10.0.0.0/16
├── AZ-a 的 Subnet: 10.0.1.0/24 ◄─┐
├── AZ-b 的 Subnet: 10.0.2.0/24 ◄─┼─ 都在同一個 VPC 內網
└── AZ-c 的 Subnet: 10.0.3.0/24 ◄─┘只要在同一個 VPC,預設就可以互通!
2. Route Table 的 Local 路由
每個 VPC 都有一條神奇的路由規則:
目的地: 10.0.0.0/16 (你的 VPC)
目標: local (本地網路)這條規則的意思是:「所有要去 VPC 內部 IP 的流量,直接走內部網路就好,不用出去外面繞。」
3. AWS 的高速骨幹網路
不同 AZ 之間不是用普通網路線連接,而是 AWS 自己建的高速光纖骨幹:
- 延遲超低(通常 1-2 毫秒)
- 頻寬超大(不用擔心塞車)
- 比你家的網路快多了
哪些資源可以跨 AZ 溝通?
簡單來說:幾乎所有資源都可以!
| 想要做的事 | 可以嗎? | 說明 |
|---|---|---|
| AZ-a 的 EC2 連到 AZ-b 的 EC2 | ✅ 可以 | 同 VPC 就能通 |
| AZ-a 的 EC2 連到 AZ-b 的 RDS | ✅ 可以 | RDS Multi-AZ 就是這樣設計的 |
| AZ-a 的 ALB 連到 AZ-b 的 EC2 | ✅ 可以 | ALB 本來就是用來跨 AZ 分流的 |
| AZ-a 的 EC2 連到 AZ-c 的 Redis | ✅ 可以 | 設定好 Security Group 就行 |
前提條件:
- 所有資源在同一個 VPC
- Security Group 有開放對應的 Port
- Route Table 沒有被亂改(通常不會)
實際例子:一個請求怎麼跑
讓我們看一個真實的流程,假設使用者要查詢商品資料:
graph TD
User["👤 使用者<br/>查詢商品資料"] --> Internet["🌐 網際網路"]
Internet --> ALB["ALB<br/>(在 AZ-a 的 Public Subnet)"]
ALB -->|跨 AZ 通訊<br/>延遲 1-2ms| EC2["EC2 應用伺服器<br/>(在 AZ-b 的 Private Subnet)"]
EC2 -->|1. 查詢商品資料| RDS["RDS 資料庫<br/>(在 AZ-b 的 Private Subnet)"]
EC2 -->|2. 查詢快取| Redis["Redis 快取<br/>(在 AZ-c 的 Private Subnet)"]
RDS -->|回傳資料| EC2
Redis -->|回傳快取| EC2
EC2 -->|組裝回應| ALB
ALB --> Internet
Internet --> User
style User fill:#e3f2fd
style ALB fill:#fff9c4
style EC2 fill:#c8e6c9
style RDS fill:#bbdefb
style Redis fill:#ffccbc流程說明:
- 使用者的請求進來,先到 AZ-a 的 ALB
- ALB 決定把請求送給 AZ-b 的 EC2(跨 AZ 通訊,但超快!)
- EC2 需要查資料,連到 AZ-b 的 RDS(同 AZ,更快)
- EC2 也查一下 AZ-c 的 Redis 快取(跨 AZ,但也很快)
- EC2 把結果組裝好,回傳給 ALB
- ALB 把回應送回給使用者
重點:整個過程都在 VPC 內部,安全又快速!
但是要注意 Security Group!
雖然不同 AZ 可以通訊,但你還是要設定 Security Group(安全群組) 來控制誰可以連誰。
簡單比喻:
- VPC 讓大家「可以」互相溝通(網路是通的)
- Security Group 控制「允許」誰溝通(防火牆)
實際配置範例
ALB 的 Security Group:
| 方向 | 規則 |
|---|---|
| 進來 (Inbound) | ✅ 允許:來自任何地方的 HTTP (Port 80) 和 HTTPS (Port 443) |
| 出去 (Outbound) | ✅ 允許:到 EC2 Security Group 的所有流量 |
EC2 的 Security Group:
| 方向 | 規則 |
|---|---|
| 進來 (Inbound) | ✅ 允許:來自 ALB Security Group 的 Port 8080;來自 RDS Security Group 的 Port 3306 |
| 出去 (Outbound) | ✅ 允許:到 RDS Security Group 的 Port 3306;到 Redis Security Group 的 Port 6379 |
RDS 的 Security Group:
| 方向 | 規則 |
|---|---|
| 進來 (Inbound) | ✅ 允許:來自 EC2 Security Group 的 Port 3306 |
| 出去 (Outbound) | 通常不用設定(RDS 只接收請求,不主動對外連線) |
關鍵技巧:用 Security Group ID 當來源
注意到了嗎?我們不是寫「允許 10.0.2.5 這個 IP」,而是寫「允許 ALB Security Group」。
好處:
- EC2 的 IP 可能會變,但 Security Group 不會變
- 更容易管理(不用記一堆 IP)
- 更安全(只有特定群組的資源能連)
總結一下
跨 AZ 通訊的關鍵觀念:
- ✅ 同一個 VPC = 同一個內網,不同 AZ 也能互通
- ✅ AWS 骨幹網路超快,跨 AZ 延遲只有 1-2 毫秒
- ✅ 幾乎所有服務都支援跨 AZ 通訊
- ⚠️ 但要設定 Security Group,控制誰可以連誰
- ⚠️ 跨 AZ 流量有成本(每 GB 約 $0.01,不過通常不多)
最重要的一句話:
把不同 AZ 想成「同一個公司在不同城市的辦公室」,它們都連在同一個公司內網,可以互相溝通,只是距離遠一點而已!
完整架構設計實戰範例
場景描述
需求: 建立一個電商網站的後端系統,要求高可用、高安全性
技術堆疊:
- 前端:透過 CloudFront CDN 提供靜態資源
- 負載平衡:Application Load Balancer
- 應用層:EC2 執行 Node.js 應用程式
- 資料層:RDS MySQL 資料庫、ElastiCache Redis
架構設計圖
graph TB
Internet["🌐 網際網路"]
CDN["CloudFront CDN"]
Internet --> CDN
subgraph VPC["VPC (10.0.0.0/16)"]
subgraph AZ-a["AZ a (ap-northeast-1a)"]
PubA["Public Subnet<br/>10.0.1.0/24"]
ALB-A["ALB (主要)"]
PrivA["Private Subnet<br/>10.0.2.0/24"]
EC2-A["EC2 App x2"]
RDS-A["RDS (主要)"]
PubA --> ALB-A
ALB-A --> PrivA
PrivA --> EC2-A
PrivA --> RDS-A
end
subgraph AZ-b["AZ b (ap-northeast-1b)"]
PubB["Public Subnet<br/>10.0.3.0/24"]
ALB-B["ALB (備援)"]
PrivB["Private Subnet<br/>10.0.4.0/24"]
EC2-B["EC2 App x2"]
RDS-B["RDS (備用)"]
PubB --> ALB-B
ALB-B --> PrivB
PrivB --> EC2-B
PrivB --> RDS-B
end
subgraph AZ-c["AZ c (ap-northeast-1c)"]
PrivC["Private Subnet<br/>10.0.5.0/24"]
Redis["Redis Cluster"]
EC2-C["備用 EC2"]
PrivC --> Redis
PrivC --> EC2-C
end
end
CDN --> ALB-A
CDN --> ALB-B
style Internet fill:#ffcccb
style CDN fill:#fff9c4
style VPC fill:#f0f0f0
style AZ-a fill:#e1f5ff
style AZ-b fill:#fff4e1
style AZ-c fill:#e8f5e9
style ALB-A fill:#90caf9
style ALB-B fill:#90caf9
style EC2-A fill:#a5d6a7
style EC2-B fill:#a5d6a7
style EC2-C fill:#a5d6a7
style RDS-A fill:#ce93d8
style RDS-B fill:#ce93d8
style Redis fill:#ffab91讓我們拆解這個架構
看完上面的圖,你可能覺得有點複雜。別擔心,我們一層一層來看。
第一層:門面(Public Subnet)
想像這是你店面的「櫃台」,客人進來第一個看到的地方。
我們在 AZ-a 和 AZ-b 都放了 ALB(負載平衡器):
- 就像在兩個城市都開店,任何一家店關門,客人還能去另一家
- ALB 會自動判斷:「欸,AZ-a 的櫃檯人太多了,把客人引導到 AZ-b 吧」
- 這就是為什麼 ALB 必須至少在兩個 AZ,AWS 的硬性規定
為什麼要這樣?
假設 AZ-a 的 ALB 掛了,網站不會掛掉,因為 AZ-b 的 ALB 馬上接手。DNS 會自動把流量導過去,使用者根本不會發現。
第二層:工作區(Private Subnet – 應用層)
這是你的「辦公室」,員工在這裡處理訂單、查資料。客人看不到,但這裡才是做事的地方。
我們在 AZ-a 和 AZ-b 各放 2 台 EC2 伺服器:
- 為什麼要 2 台?因為 1 台掛了,另 1 台還能撐著
- 為什麼要兩個 AZ?因為整個 AZ 掛了,另一個 AZ 的伺服器繼續跑
Auto Scaling 的魔法:
想像你開餐廳,平日只需要 4 個廚師,但週末客人暴增,系統會自動叫更多廚師來幫忙:
- 平常: 4 台 EC2(每個 AZ 各 2 台)
- 開始忙: 自動擴展到 6 台
- 超級忙: 最多可以擴展到 12 台
- 人少了: 自動縮減回 4 台,省成本
更新程式時怎麼辦?
這是最酷的部分!我們用「滾動更新」:
- 先更新 AZ-a 的第 1 台 EC2,ALB 把流量都導到其他台
- 更新完成後,再更新第 2 台
- 接著更新 AZ-b 的伺服器
- 全程網站不停機!
第三層:金庫(Private Subnet – 資料層)
這是最重要的地方:資料庫和快取,就像公司的金庫和檔案室。
RDS 資料庫(跨 AZ-a 和 AZ-b):
這裡有個超酷的機制叫「Multi-AZ」:
- 平常: 主要資料庫在 AZ-a 處理所有讀寫
- 背後: AWS 偷偷把資料同步複製到 AZ-b 的備用資料庫
- 災難發生: AZ-a 掛了?沒關係,1-2 分鐘內自動切換到 AZ-b
- 神奇的地方: 你的程式連接的網址(DNS endpoint)不用改,自動指向新的資料庫
就像你的銀行帳戶,不管你去哪個分行,看到的都是同一個帳戶餘額。
Redis 快取(在 AZ-c):
為什麼把快取獨立放在第三個 AZ?
- 快取掛了不會影響主要功能,只是變慢一點
- 這樣可以省點成本(不用在每個 AZ 都放快取)
實戰演練:如果真的出事了會怎樣?
讓我們模擬兩個真實場景,看看系統怎麼反應。
情境 1:整個 AZ-a 停電了 ⚡
凌晨 3 點,AZ-a 機房突然停電…
❌ 會受影響的:
- AZ-a 的 ALB 掛了
- AZ-a 的 2 台 EC2 掛了
- AZ-a 的主要 RDS 資料庫掛了
✅ 系統自動做的事(你不用做任何事):
0-30 秒:
- DNS 偵測到 AZ-a 的 ALB 沒回應
- 立刻把所有流量導向 AZ-b 的 ALB
30 秒 – 2 分鐘:
- AZ-b 的 2 台 EC2 開始承接所有流量
- Auto Scaling 偵測到負載變高,開始啟動新的 EC2 實例
- RDS 自動故障轉移到 AZ-b 的備用資料庫
2 分鐘後:
- 新的 EC2 實例上線,流量分散開來
- AZ-c 的 Redis 快取完全不受影響
- 服務恢復正常
用戶體驗:
- 前 1-2 分鐘可能有點慢,或是少數請求失敗
- 之後完全正常
- 大部分人可能根本沒發現出事了
情境 2:某台 EC2 當機了 💥
下午 2 點,AZ-a 的其中一台 EC2 突然當機…
❌ 影響: 就一台 EC2 掛了
✅ 系統自動反應:
30 秒內:
- ALB 健康檢查發現這台 EC2 沒回應
- 立刻停止送請求給這台
2-5 分鐘內:
- Auto Scaling 發現實例數量不足
- 自動啟動一台新的 EC2
- 新 EC2 準備好後,ALB 開始送流量給它
用戶體驗:
- 幾乎無感!因為還有其他 3 台 EC2 在正常服務
- 可能只有極少數正在處理中的請求會失敗
總結
核心要點回顧
- 高可用架構的基石
- 將 Public Subnet 和 Private Subnet 分散到不同 AZ,是實現高可用性的關鍵策略
- 這不僅是技術最佳實踐,更是業務連續性的保障
- 跨 AZ 通訊的本質
- 同一 VPC 內的不同 AZ 資源可以無縫通訊
- 透過 AWS 內部高速網路,延遲極低,無需擔心效能問題
- 正確配置 Security Group 和 Route Table 是關鍵
- 架構設計的平衡
- 在高可用性、成本和複雜度之間找到平衡點
- 至少 2 個 AZ 是底線,3 個 AZ 是生產環境的理想配置
- 根據業務重要性決定哪些資源需要跨 AZ 部署
- 持續優化與演練
- 架構設計不是一次性的工作,需要持續監控和優化
- 定期進行災難復原演練,確保團隊熟悉應對流程
- 關注 AWS 的新服務和最佳實踐更新
最後的話
雲端架構設計是一門藝術,也是一門科學。高可用性不是一蹴而就的,而是透過精心設計、持續優化和實戰演練逐步建立起來的。
記住這句話:「希望不是策略,但準備是。」 當故障發生時(而不是如果),你的架構設計將決定服務是繼續運作還是完全停擺。
從今天開始,將跨 AZ 高可用架構作為你設計系統的預設選擇,而不是可選項。你的使用者會感謝你,你的老闆會感謝你,你的團隊也會感謝你。
祝你在 AWS 的學習旅程中一切順利!