任務隊列函數利用 Google Cloud Tasks幫助您的應用在主應用程序流之外異步運行耗時、資源密集或帶寬受限的任務。
例如,假設您想為當前託管在具有速率限制的 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 定價。
創建任務隊列函數
要使用任務隊列功能,請遵循以下工作流程:
- 使用 Firebase SDK for Cloud Functions 編寫任務隊列函數。
- 使用 Firebase Local Emulator Suite 測試您的功能。
- 使用 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 個任務。這有助於確保對底層功能的穩定請求流,並有助於減少活動實例和冷啟動的數量。
使用 Firebase Local 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 從受信任的服務器環境(例如適用於 Firebase 的 Cloud Functions)將任務隊列函數排入 Cloud Tasks 中。如果您不熟悉 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 Tasks 等待任務完成的最長時間。 Cloud Tasks 將在隊列的重試配置之後或直到達到此截止日期之前重試任務。在示例中,隊列配置為最多重試任務 5 次,但如果整個過程(包括重試嘗試)花費的時間超過 5 分鐘,任務將自動取消。
故障排除
打開 Cloud Tasks 日誌記錄
來自 Cloud Tasks 的日誌包含有用的診斷信息,例如與任務關聯的請求的狀態。默認情況下,來自 Cloud Tasks 的日誌被關閉,因為它可能會在您的項目中生成大量日誌。我們建議您在積極開發和調試任務隊列功能時打開調試日誌。請參閱打開日誌記錄。
IAM 權限
在對任務進行排隊或 Cloud Tasks 嘗試調用您的任務隊列函數時,您可能會看到PERMISSION DENIED
錯誤。確保您的項目具有以下 IAM 綁定:
用於將任務排隊到 Cloud Tasks 的身份需要
cloudtasks.tasks.create
IAM 權限。在示例中,這是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