💡 先搞懂問題
虛構的「青松物流」有一個線上下單系統。顧客按下「送出訂單」之後,系統要通知倉庫出貨、請帳務系統開發票,再寄一封確認簡訊。第一版的寫法很直覺:下單 API 依序呼叫這三個服務,全部成功才回應顧客「下單完成」。上線後問題一個接一個出現:倉庫系統每天凌晨更新要停機十分鐘,這十分鐘內所有訂單都失敗;促銷活動一開始,每秒湧入的請求直接壓到帳務資料庫,整個網站跟著變慢;行銷部門想再加一個「會員點數」系統,工程師只好又改一次下單程式,重新測試、重新部署。
這些問題的根源是緊耦合(tight coupling):上游要等下游回應,下游一慢或一掛,上游就跟著失敗;每多一個下游,上游就多一段程式。解法是解耦(decoupling):在兩者中間放一層「先把事情收下、之後再處理」的機制,讓下單只負責把「有一筆新訂單」這件事交出去,誰要處理、什麼時候處理、失敗了怎麼重試,交給中間那一層與各個下游自己決定。AWS 上最常用的三個工具就是本頁的主角:Amazon SQS(Simple Queue Service,佇列)、Amazon SNS(Simple Notification Service,發布訂閱)與 Amazon EventBridge(事件匯流排)。
生活比喻:餐廳的出餐流程
想像一家生意很好的餐廳。外場服務生把點單夾到廚房的出單軌道上,就回去招呼下一桌客人,不必站在廚房門口等菜做好;廚師有空就從軌道上取下一張點單,取下來的點單暫時不在軌道上,別的廚師不會重複去做。如果某張單被拿走後過了好一陣子都沒出菜,可能那位廚師被叫去處理別的事,店裡的規矩是把點單重新掛回軌道,讓其他廚師接手。有一張單寫著廚房根本做不出來的菜,被掛回去、拿下來、又掛回去,退了三次之後,就改夾到店長的「問題單」夾子裡,等店長來處理,免得它一直卡在軌道上。
餐廳裡還有另外兩種溝通方式。老闆要宣布「今天鮭魚賣完」時,會用廣播,外場、廚房、櫃台同時聽到,每個人各自決定要做什麼;店裡的總機則會依來電內容轉接:要訂位轉給櫃台、要外送轉給外送組、客訴轉給店長,總機自己不處理這些事,只負責判斷要轉給誰。
這個比喻有三個地方和實際不同,剛好也是考試愛考的地方。第一,真實的廚房一張點單只會交給一位廚師,但 SQS 的標準佇列(standard queue)保證的是「至少傳遞一次」(at-least-once),偶爾同一則訊息會交給兩個消費者,所以處理程式要寫成重複執行也不會出錯,這叫等冪(idempotent);真的不能重複時,要改用 FIFO 佇列。第二,廣播沒聽清楚的人還能問同事,SNS 則是推完就不保留訊息,訂閱端當下收不到只能靠重試與訂閱層級的 DLQ;所以需要「先保留、慢慢處理」時,常見做法是在 SNS 後面各接一條 SQS 佇列,這個組合叫扇出(fan-out)。第三,總機轉接時多少會判斷輕重緩急,EventBridge 只做事件模式比對與轉送,真正的處理邏輯要寫在目標(target)裡,例如 Lambda 函式或 Step Functions 狀態機。
新手最常卡在哪裡
第一個坑是可見性逾時設得比處理時間短:消費者還在處理,訊息就重新出現、被另一個消費者拿走,同一張訂單出貨兩次。第二個坑是沒有設 DLQ:一則格式錯誤的訊息永遠處理失敗,就在佇列裡一直被拿出來、放回去,白白消耗運算資源;在 FIFO 佇列裡更糟,它會卡住同一個訊息群組後面的所有訊息。第三個坑是選錯服務:把 SNS 當緩衝、用 SQS 做多方通知、把多步驟流程硬拆成一串佇列。實驗室一處理前兩個坑,實驗室二處理第三個。
🎮 互動實驗室一:SQS 處理模擬器
青松物流的出貨佇列裡有 5 張訂單,由三個消費者 A、B、C 同時處理。其中訂單 #102 的地址欄格式錯誤,是一則毒訊息(poison message):每次處理到第 3 秒就拋出例外、沒有刪除。左邊調整佇列類型、可見性逾時、正常訂單的處理時間、maxReceiveCount 與是否設定 DLQ,右邊按「下一個事件」一步一步看訊息被接收、刪除、逾時重現,或被移到 DLQ;也可以按「自動播放」。設定一改,模擬就從頭開始。跑完會檢查下方三個挑戰目標有沒有達成,並說明原因。
一、佇列設定
二、挑戰目標
| 項目 | 標準佇列 | FIFO 佇列 |
|---|---|---|
| 順序 | 盡力而為,可能亂序 | 同一個訊息群組內先進先出 |
| 重複 | 至少一次,偶爾重複 | 5 分鐘去重間隔內只處理一次 |
| 吞吐量 | 幾乎沒有上限 | 每個分割區每秒 300 次(批次 3,000 則);高吞吐量模式更高 |
| 名稱 | 最多 80 字元 | 必須以 .fifo 結尾 |
來源佇列 orders-shipping
DLQ orders-dlq
行為依 Amazon SQS 開發人員指南「可見性逾時」「寄不出的信件佇列」與 API 參考的 SetQueueAttributes、DeleteMessage(查證時間 2026 年 10 月)。為了讓畫面看得懂,模擬做了幾個簡化:時間以秒為單位、消費者一次只拿一則訊息、閒置的消費者會立刻來拉;標準佇列依編號順序交付,實際上順序只是盡力而為,也可能偶發重複傳遞。處理完要刪除時,若期間訊息已被別人重新收到,舊的收據控制碼(receipt handle)不保證刪得掉,模擬一律當作沒刪掉;若沒有被重新收到,模擬當作刪除成功。
🎮 互動實驗室二:情境分診,這該用哪個服務?
下面有 10 張虛構公司的情境卡。讀完情境與卡片下方的關鍵需求,從 7 個選項裡點一個你認為最適合的服務或組合,畫面會立即說明對錯與原因;答錯也可以再點其他選項看看差在哪。上方的圓點可以跳到任一張卡,全部答完會顯示總結。
🛠️ 操作教學:SNS 主題扇出到兩條 SQS 佇列,並設定 DLQ
不用登入 AWS,也能先把流程走一遍:建立一個 SNS 主題、一條 DLQ、兩條設好重新驅動政策的工作佇列,讓主題可以把訊息送進佇列,訂閱、發布一則測試訊息,最後看兩條佇列都收到。左邊是簡化的主控台,右邊同步顯示等效的 AWS CLI、CloudFormation 與 CLI 要讀的 JSON 檔,黃色底的那幾行就是目前這一步對應的內容。可以故意填錯名稱或數字看看驗證訊息,也可以改區域、主題名稱或佇列類型,看右邊怎麼跟著變。
自己動手時要注意
權限方面,操作的身分需要 sns:CreateTopic、sns:Subscribe、sns:Publish、sqs:CreateQueue、sqs:GetQueueAttributes、sqs:SetQueueAttributes、sqs:ReceiveMessage、sqs:DeleteMessage,以及練習完刪除用的 sns:DeleteTopic、sqs:DeleteQueue;用 CloudFormation 的話還要能建立與刪除堆疊。注意「SNS 能不能把訊息送進佇列」不是看你的權限,而是看佇列上的存取政策(resource-based policy),所以第 5 步不能省;條件裡的 aws:SourceArn 限定只有這個主題能送,避免其他主題或帳戶冒用(confused deputy)。
費用方面,SNS 與 SQS 都是依請求次數計費,練習量通常很小,但長輪詢以外的空輪詢、迴圈裡不斷重試的毒訊息都會累積請求數;2025-07-15 之後建立的帳戶適用 Free Tier 新制(註冊抵用金與免費方案、付費方案兩種帳戶方案),用量從抵用金扣除,實際條件以 AWS Free Tier 頁面為準。佇列刪除後,60 秒內不能再建立同名佇列。練習完依下面的順序刪除:
範例裡的帳戶 ID 一律是官方文件慣用的 111122223333,名稱也都是示意。不要把存取金鑰寫進腳本或截圖;在 CloudShell 或用 IAM Identity Center 登入的終端機操作,就不需要長期金鑰。訊息內容不要放個資或密碼,主題名稱也一樣,官方提醒主題名稱會出現在 CloudWatch Logs 等其他服務裡。
📘 原理補完
三兄弟(加上兩位常被拿來比較的鄰居)
先用一張表把傳遞方式分清楚。判斷的關鍵不是「哪個比較新」,而是三個問題:訊息由誰主動送出(拉還是推)、一則訊息給幾個接收者、送出去之後要不要保留。下表依 AWS 官方文件與本站節點整理,數字的查證時間是 2026 年 10 月:
| 服務 | 傳遞方式 | 一則訊息給誰 | 保留 | 順序與重複 | 典型用途 |
|---|---|---|---|---|---|
| SQS 標準佇列 | 消費者拉取 | 一個消費者 | 預設 4 天,1 分鐘~14 天 | 盡力排序;至少一次,偶爾重複 | 削峰填谷、工作分派、重試 |
| SQS FIFO 佇列 | 消費者拉取 | 一個消費者 | 同上 | 群組內先進先出;5 分鐘去重間隔內只處理一次 | 同一帳戶、同一訂單的事件要依序處理 |
| Amazon SNS | 主題推送 | 每個訂閱者各一份 | 不保留,只重試 | 標準主題盡力排序;FIFO 主題保序去重 | 扇出、通知人(Email、簡訊、推播) |
| Amazon EventBridge | 匯流排依規則推送 | 符合規則的目標(每條規則最多 5 個) | 可另外封存再重播 | 不保證順序 | AWS 服務與 SaaS 事件、依內容路由、排程 |
| Kinesis Data Streams | 消費者讀取 | 多個消費者各自讀同一份 | 預設 24 小時,最長 365 天 | 同一分片內有序,可重播 | 大量即時串流、多個應用重讀 |
| AWS Step Functions | 狀態機呼叫各步驟 | 依流程定義 | Standard 執行歷程保留 90 天 | Standard 每步 exactly-once | 多步驟、要等待與補償的流程 |
SQS 訊息的一生:可見性逾時與收據控制碼
生產者用 SendMessage 放進訊息後,訊息處於「可見」狀態。消費者呼叫 ReceiveMessage 取得訊息時,SQS 會一併給它一個收據控制碼(receipt handle),同時開始可見性逾時的倒數:這段時間內其他消費者看不到這則訊息。消費者處理完,必須用這個收據控制碼呼叫 DeleteMessage,訊息才真正從佇列消失;SQS 不會因為「被收走」就自動刪除。如果逾時到了還沒刪除,訊息會重新變成可見,下一個來拉的消費者會再收到一次,而且每次收到的收據控制碼都不一樣。官方文件說明,要刪除時必須用最近一次收到的收據控制碼,用舊的那個請求雖然會成功,訊息卻可能沒被刪掉,這正是實驗室一裡「處理完卻刪不掉」的原因。
幾個數字要記住:可見性逾時預設 30 秒,可設 0 秒到 12 小時;設成 0 等於立刻放回佇列。標準佇列同時處於「已接收、未刪除」狀態的訊息(in-flight)大約以 120,000 則為上限。長輪詢(long polling)讓 ReceiveMessage 最多等 20 秒、有訊息才回應,能減少空回應與請求費用。用 Lambda 處理 SQS 時,是 Lambda 的事件來源對應替你輪詢,函式成功結束才刪除訊息;Lambda 官方文件建議把佇列的可見性逾時設成至少函式逾時的 6 倍,否則函式還在跑、訊息就被另一個函式執行環境收走。
寄不出的信件佇列(DLQ)與重新驅動
DLQ 本身就是一條普通的 SQS 佇列,差別只在它被別的佇列的重新驅動政策(redrive policy)指定為目的地。來源佇列的 RedrivePolicy 屬性是一段 JSON,包含 deadLetterTargetArn(DLQ 的 ARN)與 maxReceiveCount:一則訊息的接收次數超過這個值仍未被刪除,SQS 就把它移到 DLQ。官方文件的限制與建議有幾條:DLQ 必須和來源佇列在同一個帳戶、同一個區域,而且類型相同(FIFO 配 FIFO、標準配標準);SQS 不會自動建立 DLQ,要先建好;maxReceiveCount 設太低(例如 1),一次暫時性失敗就會被送走,要留足重試次數。
還有一個容易忽略的細節是保留期間。標準佇列的訊息到期時間一律從「最初進入來源佇列」的時間算起,移到 DLQ 不會重新計時;所以官方建議 DLQ 的保留期間要設得比來源佇列長,常見做法是直接設最長的 14 天,免得訊息一進 DLQ 就快過期。FIFO 佇列則相反,移到 DLQ 時會重新計時。DLQ 這一端可以用重新驅動允許政策(redrive allow policy)限制哪些來源佇列能用它;修好程式之後,可以用 DLQ 重新驅動(DLQ redrive)把訊息搬回來源佇列重新處理。
標準佇列與 FIFO 佇列
標準佇列追求吞吐量,官方說法是幾乎沒有上限,代價是順序只是盡力而為,偶爾會重複傳遞。FIFO 佇列的名稱必須以 .fifo 結尾,建立後不能改類型。每則訊息都要帶訊息群組 ID(message group ID),同一個群組內嚴格先進先出,而且前一則還沒刪除,同群組的下一則就不會被交出去;不同群組之間可以平行處理,所以群組 ID 通常設成「需要保序的單位」,例如帳戶 ID 或訂單 ID。去重靠去重 ID(deduplication ID)或開啟內容型去重(content-based deduplication),在 5 分鐘的去重間隔內,相同 ID 的訊息只會被接受一次。
吞吐量方面,FIFO 佇列不開高吞吐量模式時,每個分割區、每種 API 動作每秒 300 次,用批次(一次最多 10 則)可達每秒 3,000 則;開啟高吞吐量模式後上限高很多,數字依區域不同。另外要分清楚:FIFO 的「只處理一次」指的是傳送端的去重,消費者若沒在可見性逾時內刪除,訊息一樣會重新交付,處理程式仍然要能承受重試。
SNS 扇出、篩選政策與佇列存取政策
SNS 主題的訂閱分成應用程式對應用程式(A2A,例如 SQS、Lambda、HTTP/S 端點、Data Firehose)與應用程式對人(A2P,例如 Email、簡訊、行動推播)。扇出就是一個主題訂閱多條 SQS 佇列:發布一次,每條佇列各自拿到一份,各自緩衝、各自重試、各自設 DLQ;新增下游只要多一個訂閱,發布端完全不用改。訂閱上可以設篩選政策(filter policy),只收符合訊息屬性或內容的訊息,不必為每種事件各開一個主題。
要讓 SNS 把訊息送進佇列,佇列上必須有一條存取政策,允許 sns.amazonaws.com 執行 sqs:SendMessage,並用 aws:SourceArn 條件限定是哪一個主題;同一個帳戶的佇列訂閱會自動確認。訂閱可以開啟原始訊息傳遞(raw message delivery),佇列收到的就是發布的內容本身,而不是包了一層 SNS 中繼資料的 JSON。主題分標準與 FIFO 兩種,建立後不能改類型;FIFO 主題主要搭配 FIFO 佇列做保序扇出,也可以訂閱標準佇列,但那條佇列就只剩盡力排序;標準主題則不能訂閱 FIFO 佇列。
EventBridge:規則、Scheduler 與 Pipes
Amazon EventBridge 的前身是 CloudWatch Events。事件匯流排分三種來源:預設匯流排自動收到 AWS 服務事件(例如 EC2 狀態變更、GuardDuty 發現),自訂匯流排收自家應用程式用 PutEvents 送進來的事件,合作夥伴匯流排收支援的 SaaS 事件。規則用事件模式(event pattern)比對事件的 JSON 內容,符合就送到目標,每條規則最多 5 個目標(不可調整);事件可以封存,日後重播回原本的匯流排,用來測試新規則或補處理。另外兩個功能常被考:EventBridge Scheduler 是無伺服器排程器,支援 cron、rate 與一次性排程,能直接呼叫數百種 AWS API;EventBridge Pipes 是點對點管線,從單一來源(SQS、Kinesis、DynamoDB Streams 等)讀取,經篩選與可選的豐富化,送到單一目標。事件大小上限在 2026-01 由 256 KB 調高到 1 MB(查證日期 2026-10-07)。
遇到題目時的判斷步驟
- 是不是有先後順序、要等待或分支的多步驟流程?是就選 Step Functions,不要用一串佇列自己串。
- 是不是依時間觸發(每天、每 15 分鐘、某個日期一次)?是就選 EventBridge Scheduler(或排程規則),取代 EC2 上的 cron。
- 是不是大量串流、多個應用要讀同一份資料、要能重播?是就選 Kinesis Data Streams(或 Amazon MSK)。
- 一則訊息只給一個處理者?選 SQS;順序或不重複是硬需求選 FIFO,否則選標準佇列。
- 要給多個接收者?要依事件內容路由、接 AWS 服務或 SaaS 事件、要封存重播,選 EventBridge 規則;要高吞吐的扇出或直接通知人,選 SNS,需要緩衝與重試就在後面接 SQS。
容易考錯的地方
SQS 收走訊息就等於刪除:不是。ReceiveMessage 只是讓訊息暫時隱藏,處理完要自己呼叫 DeleteMessage;忘了刪除,逾時後就會重複處理。
重複處理就加長保留期間或開長輪詢:都無關。重複處理的原因是可見性逾時比處理時間短,解法是加長可見性逾時或在處理中用 ChangeMessageVisibility 延長;長輪詢解決的是空回應,保留期間決定訊息最多放多久。
DLQ 可以跨區域、可以混用類型:不行。DLQ 必須同帳戶、同區域、同類型。另外 DLQ 的保留期間要比來源佇列長,因為標準佇列移過去不會重新計時。
SNS 可以當緩衝:SNS 不保留訊息,訂閱端忙不過來或停機時只能靠重試。需要緩衝與慢慢處理,在 SNS 後面接 SQS;題目寫「每個系統各自處理、可以各自重試」就是扇出。
SNS 訂閱了 SQS,訊息卻沒進來:先看佇列的存取政策有沒有允許 sns.amazonaws.com 傳送,以及 aws:SourceArn 有沒有寫對主題 ARN;用 KMS 客戶管理金鑰加密的佇列,還要讓 SNS 能使用那把金鑰。
要順序就一律選 FIFO:FIFO 有吞吐量上限,而且只保證同一個訊息群組內的順序。題目只說「高吞吐、可以接受偶爾重複」時,標準佇列加上等冪的處理程式才是正解。
EventBridge 和 SNS 都能一對多,所以隨便選:看關鍵字。「AWS 服務事件」「SaaS」「依事件內容的欄位路由」「封存重播」「Schema Registry」指向 EventBridge;「Email、簡訊、行動推播」「大量扇出到 SQS」指向 SNS。
Kinesis Data Streams 和 SQS 都是佇列:SQS 的訊息處理完就刪除,一則給一個消費者;Kinesis 的資料保留一段時間,多個消費者各自讀取、可以重播。「多個應用讀同一份資料」「重播」是分界點。
相關考試:SQS、SNS、EventBridge 都列在 CLF-C02、SAA-C03、DVA-C02、SOA-C03、DEA-C01、SAP-C02、DOP-C02 等考試的範圍內(依 AWS 官方考試指南,查證時間 2026 年 10 月)。CLF-C02 著重「解耦與非同步」的觀念與服務辨識;SAA-C03 與 SAP-C02 著重情境選擇;DVA-C02 與 SOA-C03 則會考可見性逾時、DLQ、長輪詢等設定細節。
✅ 自我檢測
6 題原創題,選完立即顯示對錯與解析,全部作答後會出現總分。目前得分:0 / 6