Queues
一個 Worker 把訊息丟進佇列後立刻回覆;另一個 Worker 之後再成批取出處理,還會自動重試——而且一則訊息都不會弄丟。
Queues 是什麼?
Cloudflare Queues 是一個「訊息佇列(message queue)」:一條可靠的排隊線,一個 Worker 把訊息放進去,另一個 Worker 之後再取出來處理。它保證送達,所以就算接收方很忙、或短暫出錯,訊息也不會弄丟。
「訊息(message)」就是一小塊資料——例如「寄歡迎信給使用者 123」或「把這張剛上傳的照片縮圖」。與其讓使用者乾等你做完那件慢事,你把訊息丟進佇列、馬上回應,慢工作就在背景進行。
把它想成…
佇列就像餐廳的點餐夾單軌。服務生(一個 Worker)把點餐單夾上去後,就回去招呼客人;廚房(另一個 Worker)有空時把單子取下來,一次煮好幾張。沒有人要站在櫃檯前面等餐做好。
為什麼要用它?
如果你的 Worker 想在「一次請求」裡把所有事做完,慢任務會讓使用者乾等,而且一出錯整個工作就沒了。佇列把「接下工作」和「執行工作」拆開,讓你的 App 更快、也可靠許多。
立刻回應
幾毫秒內就先確認收到請求,再把粗重工作丟到背景做。
保證送達
訊息會一直保存到成功處理為止——就算當機、重啟也還在。
自動重試
如果處理失敗,訊息會自動重試。不用自己寫重試的程式碼。
成批處理
一次最多處理 100 則訊息,做大量工作時效率大幅提升。
免流出流量費
訊息流出佇列的頻寬,永遠不收費。
削平尖峰
突然湧入的大量工作會安全地堆在佇列裡,而不是把你的系統壓垮。
什麼時候該用?
只要某件工作「可以晚點做、不用馬上做」,或是系統的某一部分需要安全地把工作交給另一部分,就用 Queues。
寄送 email
把歡迎信或收據信丟進佇列,讓使用者的請求立刻返回。
媒體處理
上傳之後,在背景縮圖或轉檔影片。
Webhook
快速接住外部送來的 webhook,再帶著重試機制可靠地處理。
Worker 對 Worker
在 Workers 之間傳遞工作,而不用它們彼此直接呼叫。
批次匯入
先把事件緩衝起來,再以高效率的批次寫入儲存。
通知推送
推播或站內通知時,不會卡住原本的請求。
怎麼開始用?
你用 Wrangler 建立一個佇列,然後把一個 Worker 設成 producer(生產者,負責送訊息),把另一個 handler 設成 consumer(消費者,負責處理)。同一個 Worker 也可以同時兼任兩者。
建立佇列
用一個名稱建立新佇列。訊息就會在這裡排隊等候。
npx wrangler queues create my-queue在設定檔加上綁定
在 wrangler.jsonc 裡,把佇列宣告成 producer(讓 Worker 能送訊息進去)以及 consumer(讓 Worker 被叫來處理一批批訊息)。
{ "queues": { "producers": [ { "queue": "my-queue", "binding": "MY_QUEUE" } ], "consumers": [ { "queue": "my-queue", "max_batch_size": 10, "max_batch_timeout": 5 } ] } }部署
發佈你的 Worker。用 wrangler tail 就能即時看到訊息被消費的過程。
npx wrangler deploy npx wrangler tail
export default {
// PRODUCER: runs on each HTTP request and sends a message
async fetch(request, env, ctx) {
await env.MY_QUEUE.send({
url: request.url,
time: Date.now(),
});
return new Response("Queued!");
},
// CONSUMER: runs in the background with a batch of messages
async queue(batch, env, ctx) {
for (const message of batch.messages) {
console.log("Processing:", message.body);
// ...do the slow work here...
message.ack(); // mark this message as done
}
},
};ack 與重試
訊息成功處理完就呼叫 message.ack()(確認)。如果你的消費者丟出錯誤、或呼叫 message.retry(),Queues 之後會重新投遞那則訊息——直到達到重試上限——所以失敗會自我修復。
重點概念
Producer(生產者)
用 env.QUEUE.send() 把訊息送進佇列的那個 Worker。
Consumer(消費者)
Cloudflare 會帶著一批批訊息來呼叫的 queue() 處理函式。
Batch(批次)
一次最多 100 則訊息一起送來,方便高效率地處理。
確認(ack)
把訊息標記成「成功完成」,這樣它就不會被再送一次。
重試(retry)
失敗的訊息會被自動重新投遞,最多 100 次。
死信佇列(DLQ)
訊息用完所有重試後會被送到的另一個佇列,方便你事後檢查它們。
小提示與計費
一定要設死信佇列
設定一個死信佇列(dead letter queue),讓一直失敗的訊息不會憑空消失——它們會落到一個你之後能檢查、修復的地方,而不是用完重試後就被丟掉。
值得記住的限制
- 每個帳號最多 10,000 個佇列
- 最大訊息大小:128 KB
- 最大批次:100 則訊息(或合計 256 KB)
- 最長批次等待:60 秒
- 吞吐量:每個佇列最多 5,000 則訊息/秒
- 重試:最多 100 次;保留期可設定到最多 14 天
免費起步、不收流出費
Queues 在免費與付費方案都能用,而且永遠不收 egress(流出流量)費用。免費方案的訊息保留期固定為 24 小時。