工作佇列函式會運用 Google Cloud Tasks,協助應用程式在主要應用程式流程之外,以非同步方式執行耗時、耗用大量資源或頻寬受限的工作。
舉例來說,假設您想備份目前在 API 上託管的大量圖片檔案,但 API 有速率限制。如要成為該 API 的負責任消費者,您必須遵守其速率限制。此外,這類長時間執行的工作可能會因逾時和記憶體限制而失敗。
為減輕這項複雜度,您可以編寫工作佇列函式,設定 scheduleTime 和 dispatchDeadline 等基本工作選項,然後將函式交給 Cloud Tasks 中的佇列。Cloud Tasks
這個環境專為確保這類作業的有效壅塞控制和重試政策而設計。
Firebase SDK for Cloud Functions for Firebase v3.20.1 以上版本可與 Firebase Admin SDK v10.2.0 以上版本互通,支援工作佇列函式。
在 Firebase 中使用工作佇列函式可能會產生Cloud Tasks處理費用。詳情請參閱Cloud Tasks定價。
建立工作佇列函式
如要使用工作佇列函式,請按照下列工作流程操作:
- 使用 Cloud Functions 的 Firebase SDK 編寫工作佇列函式。
- 使用 HTTP 要求觸發函式,測試函式。
- 使用 Firebase CLI 部署函式。首次部署工作佇列函式時,CLI 會在 Cloud Tasks 中建立工作佇列,並使用原始碼中指定的選項 (速率限制和重試)。
- 將工作新增至新建立的工作佇列,並視需要傳遞參數來設定執行時間表。如要達成這個目標,請使用 Admin SDK 編寫程式碼,然後部署至 Cloud Functions for Firebase。
編寫工作佇列函式
使用 onDispatch 開始撰寫工作佇列函式。編寫工作佇列函式時,請務必設定每個佇列的重試和速率限制設定。本頁面的程式碼範例是以應用程式為基礎,該應用程式會設定服務,備份 NASA「每日天文一圖」的所有圖片:
設定工作佇列函式
工作佇列函式提供一組強大的設定,可精確控制工作佇列的速率限制和重試行為:
exports.backupApod = functions
.runWith( {secrets: ["NASA_API_KEY"]})
.tasks.taskQueue({
retryConfig: {
maxAttempts: 5,
minBackoffSeconds: 60,
},
rateLimits: {
maxConcurrentDispatches: 6,
},
}).onDispatch(async (data) => {
retryConfig.maxAttempts=5:工作佇列中的每個工作最多會自動重試 5 次。這有助於減輕暫時性錯誤,例如網路錯誤或依附的外部服務暫時中斷。retryConfig.minBackoffSeconds=60:每次重試間隔至少 60 秒。這會在每次嘗試之間提供大量緩衝區,因此我們不會急著太快用完 5 次重試嘗試。rateLimits.maxConcurrentDispatch=6:一次最多可調度 6 項工作。這有助於確保基礎函式持續收到要求,並減少有效執行個體和冷啟動的數量。
測試工作佇列函式
在大多數情況下,Cloud Functions 模擬器是測試工作佇列函式的最佳方式。請參閱 Emulator Suite 說明文件,瞭解如何為工作佇列函式模擬作業設定應用程式。
此外,工作佇列函式會在 Firebase Local Emulator Suite 中公開為簡單的 HTTP 函式。您可以傳送含有 JSON 資料酬載的 HTTP POST 要求,測試模擬的工作函式:
# start the Firebase Emulators
firebase emulators:start
# trigger the emulated task queue function
curl \
-X POST # An HTTP POST request...
-H "content-type: application/json" \ # ... with a JSON body
http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
-d '{"data": { ... some data .... }}' # ... with JSON encoded data
部署工作佇列函式
使用 Firebase CLI 部署工作佇列函式:
$ firebase deploy --only functions:backupApod
首次部署工作佇列函式時,CLI 會在 Cloud Tasks 中建立工作佇列,並使用原始碼中指定的選項 (速率限制和重試)。
如果在部署函式時發生權限錯誤,請確認已將適當的 IAM 角色指派給執行部署指令的使用者。
將工作佇列函式排入佇列
工作佇列函式可使用 Node.js 的 Firebase Admin SDK,從 Cloud Tasks 中加入佇列,例如 Cloud Functions for Firebase 等受信任的伺服器環境。如果您剛接觸 Admin SDK,請參閱「將 Firebase 新增至伺服器」一文,瞭解如何開始使用。
在一般流程中,Admin SDK 會建立新工作,並將其加入 Cloud Tasks 的佇列,然後設定工作:
exports.enqueueBackupTasks = functions.https.onRequest(
async (_request, response) => {
const queue = getFunctions().taskQueue("backupApod");
const enqueues = [];
for (let i = 0; i <= 10; i += 1) {
// Enqueue each task with i*60 seconds delay. Our task queue function
// should process ~1 task/min.
const scheduleDelaySeconds = i * 60
enqueues.push(
queue.enqueue(
{ id: `task-${i}` },
{
scheduleDelaySeconds,
dispatchDeadlineSeconds: 60 * 5 // 5 minutes
},
),
);
}
await Promise.all(enqueues);
response.sendStatus(200);
});
scheduleDelaySeconds:程式碼範例會為第 N 個工作關聯 N 分鐘的延遲時間,嘗試分散工作執行時間。這表示每分鐘會觸發約 1 項工作。請注意,如要讓 Cloud Tasks 在特定時間觸發工作,也可以使用scheduleTime。dispatchDeadlineSeconds:等待工作完成的最長時間。Cloud TasksCloud Tasks 會根據佇列的重試設定重試工作,或直到達到這個截止日期為止。在範例中,佇列設定為最多重試工作 5 次,但如果整個程序 (包括重試嘗試) 超過 5 分鐘,工作就會自動取消。
疑難排解
開啟 Cloud Tasks 記錄功能
Cloud Tasks 的記錄包含實用的診斷資訊,例如與工作相關聯的要求狀態。根據預設,系統會停用 Cloud Tasks 的記錄,因為這項功能可能會在專案中產生大量記錄。建議您在積極開發及偵錯工作佇列函式時,開啟偵錯記錄。請參閱「開啟記錄功能」。
IAM 權限
排隊工作時或 Cloud Tasks 嘗試叫用工作佇列函式時,可能會出現 PERMISSION DENIED 錯誤。請確認專案具有下列 IAM 繫結:
用來將工作加入佇列的 ID 必須具備 Cloud Tasks
cloudtasks.tasks.createIAM 權限。在範例中,這是App Engine預設服務帳戶
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
--role=roles/cloudtasks.enqueuer
將工作加入 Cloud Tasks 佇列時使用的身分,必須具備使用 Cloud Tasks 中與工作相關聯服務帳戶的權限。
在範例中,這是App Engine預設服務帳戶。
如要瞭解如何將App Engine預設服務帳戶新增為App Engine預設服務帳戶的使用者,請參閱 Google Cloud IAM 說明文件。
用來觸發工作佇列函式的身分必須具備
cloudfunctions.functions.invoke權限。在範例中,這是App Engine預設服務帳戶
gcloud functions add-iam-policy-binding $FUNCTION_NAME \
--region=us-central1 \
--member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
--role=roles/cloudfunctions.invoker