Thêm các hàm vào hàng đợi bằng Tác vụ trên đám mây


Các hàm hàng đợi tác vụ tận dụng Google Cloud Tasks để giúp ứng dụng của bạn chạy các tác vụ tốn thời gian, tốn nhiều tài nguyên hoặc có giới hạn băng thông một cách không đồng bộ, bên ngoài luồng ứng dụng chính của bạn.

Ví dụ: giả sử bạn muốn tạo bản sao lưu cho một tập hợp lớn các tệp hình ảnh hiện được lưu trữ trên một API có giới hạn số lượng yêu cầu. Để trở thành người dùng có trách nhiệm của API đó, bạn cần tôn trọng giới hạn số lượng yêu cầu của chúng. Ngoài ra, loại công việc chạy trong thời gian dài này có thể dễ bị lỗi do hết thời gian chờ và giới hạn bộ nhớ.

Để giảm thiểu sự phức tạp này, bạn có thể viết một hàm hàng đợi tác vụ để đặt các tuỳ chọn tác vụ cơ bản như scheduleTimedispatchDeadline, sau đó chuyển hàm đó vào một hàng đợi trong Cloud Tasks. Môi trường Cloud Tasks được thiết kế riêng để đảm bảo kiểm soát hiệu quả tình trạng tắc nghẽn và các chính sách thử lại cho các loại thao tác này.

Firebase SDK for Cloud Functions for Firebase phiên bản 3.20.1 trở lên có khả năng tương tác với SDK quản trị Firebase phiên bản 10.2.0 trở lên để hỗ trợ các hàm hàng đợi tác vụ.

Việc sử dụng các hàm hàng đợi tác vụ với Firebase có thể dẫn đến việc tính phí xử lý Cloud Tasks. Vui lòng xem mức giá của Cloud Tasks để biết thêm thông tin.

Tạo hàm cho hàng đợi tác vụ

Để sử dụng các hàm của hàng đợi tác vụ, hãy làm theo quy trình sau:

  1. Viết một hàm hàng đợi công việc bằng cách sử dụng Firebase SDK cho Cloud Functions.
  2. Kiểm tra hàm của bạn bằng cách kích hoạt hàm đó bằng một yêu cầu HTTP.
  3. Triển khai hàm bằng Giao diện dòng lệnh (CLI) của Firebase. Trong lần đầu triển khai chức năng hàng đợi tác vụ, CLI sẽ tạo một hàng đợi tác vụ trong Cloud Tasks với các tuỳ chọn (giới hạn tốc độ và thử lại) được chỉ định trong mã nguồn của bạn.
  4. Thêm tác vụ vào hàng đợi tác vụ mới tạo, chuyển các tham số để thiết lập lịch thực thi nếu cần. Bạn có thể làm được điều này bằng cách viết mã bằng SDK dành cho quản trị viên và triển khai trên Cloud Functions cho Firebase.

Ghi hàm hàng đợi tác vụ

Sử dụng onDispatch để bắt đầu viết các hàm hàng đợi tác vụ. Một phần quan trọng khi viết hàm hàng đợi tác vụ là đặt cấu hình thử lại cho mỗi hàng đợi và giới hạn số lượng yêu cầu. Mã mẫu trong trang này dựa trên một ứng dụng có chức năng thiết lập dịch vụ sao lưu tất cả hình ảnh từ Ảnh thiên văn học trong ngày của NASA:

Định cấu hình các hàm của hàng đợi tác vụ

Các hàm của hàng đợi tác vụ đi kèm với một tập hợp các chế độ cài đặt cấu hình mạnh mẽ để kiểm soát chính xác giới hạn số lượng yêu cầu và thử lại hành vi của hàng đợi tác vụ:

exports.backupApod = functions
    .runWith( {secrets: ["NASA_API_KEY"]})
    .tasks.taskQueue({
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }).onDispatch(async (data) => {
  • retryConfig.maxAttempts=5: Mỗi tác vụ trong hàng đợi tác vụ sẽ được tự động thử lại tối đa 5 lần. Việc này giúp giảm thiểu các lỗi tạm thời, chẳng hạn như lỗi mạng hoặc gián đoạn dịch vụ tạm thời của một dịch vụ phụ thuộc bên ngoài.
  • retryConfig.minBackoffSeconds=60: Mỗi tác vụ sẽ được thử lại ít nhất 60 giây sau mỗi lần thử. Điều này cung cấp một vùng đệm lớn giữa mỗi lần thử để chúng tôi không phải vội vàng thử lại 5 lần thử lại quá nhanh.
  • rateLimits.maxConcurrentDispatch=6: Tối đa 6 tác vụ được gửi đi tại một thời điểm nhất định. Điều này giúp đảm bảo luồng yêu cầu ổn định đến hàm cơ bản, đồng thời giúp giảm số lượng thực thể đang hoạt động cũng như số lượt khởi động nguội.

Kiểm thử hàm của hàng đợi tác vụ

Các hàm hàng đợi tác vụ trong Bộ mô phỏng cục bộ Firebase được hiển thị dưới dạng các hàm HTTP đơn giản. Bạn có thể kiểm thử một chức năng tác vụ được mô phỏng bằng cách gửi yêu cầu POST qua HTTP với tải trọng dữ liệu json:

 # 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

Triển khai các hàm của hàng đợi tác vụ

Triển khai chức năng hàng đợi tác vụ bằng cách sử dụng Giao diện dòng lệnh (CLI) của Firebase:

$ firebase deploy --only functions:backupApod

Trong lần đầu triển khai một chức năng hàng đợi tác vụ, CLI sẽ tạo một hàng đợi tác vụ trong Cloud Tasks với các tuỳ chọn (giới hạn tốc độ và thử lại) được chỉ định trong mã nguồn của bạn.

Nếu bạn gặp lỗi về quyền khi triển khai hàm, hãy nhớ chỉ định các vai trò quản lý danh tính và quyền truy cập (IAM) thích hợp cho người dùng đang chạy lệnh triển khai.

Thêm các hàm hàng đợi tác vụ vào hàng đợi

Các hàm hàng đợi tác vụ có thể được đưa vào hàng đợi trong Cloud Tasks từ một môi trường máy chủ đáng tin cậy, chẳng hạn như Cloud Functions cho Firebase bằng cách sử dụng SDK Quản trị của Firebase cho Node.js. Nếu bạn mới sử dụng SDK quản trị, hãy xem bài viết Thêm Firebase vào máy chủ để bắt đầu.

Trong một quy trình thông thường, SDK dành cho quản trị viên sẽ tạo một tác vụ mới, đưa tác vụ đó vào hàng đợi trong Cloud Tasks và đặt cấu hình cho tác vụ:

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: Mã mẫu cố gắng mở rộng quá trình thực thi tác vụ bằng cách liên kết độ trễ là phút thứ N cho tác vụ thứ N. Điều này đồng nghĩa với việc kích hoạt khoảng 1 tác vụ/phút. Xin lưu ý rằng bạn cũng có thể dùng scheduleTime nếu muốn Cloud Tasks kích hoạt một tác vụ vào một thời điểm cụ thể.
  • dispatchDeadlineSeconds: Khoảng thời gian tối đa Cloud Tasks sẽ chờ một tác vụ hoàn tất. Cloud Tasks sẽ thử lại tác vụ sau khi cấu hình thử lại của hàng đợi hoặc cho đến khi đạt thời hạn này. Trong mẫu này, hàng đợi được định cấu hình để thử lại tác vụ tối đa 5 lần, nhưng tác vụ đó sẽ tự động bị huỷ nếu toàn bộ quá trình (bao gồm cả lượt thử lại) mất hơn 5 phút.

Khắc phục sự cố

Bật tính năng ghi nhật ký trong Cloud Tasks

Nhật ký từ Cloud Tasks chứa thông tin chẩn đoán hữu ích như trạng thái của yêu cầu liên quan đến một tác vụ. Theo mặc định, nhật ký trong Cloud Tasks sẽ bị tắt do số lượng lớn nhật ký mà tính năng này có thể tạo trong dự án của bạn. Bạn nên bật nhật ký gỡ lỗi trong khi đang tích cực phát triển và gỡ lỗi các chức năng của hàng đợi tác vụ. Hãy xem phần Bật tính năng ghi nhật ký.

Quyền quản lý danh tính và quyền truy cập (IAM)

Bạn có thể gặp lỗi PERMISSION DENIED khi thêm các nhiệm vụ vào hàng đợi hoặc khi Cloud Tasks cố gắng gọi các chức năng trong hàng đợi nhiệm vụ của bạn. Hãy đảm bảo rằng dự án của bạn có các mối liên kết IAM sau đây:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Danh tính dùng để đưa các công việc vào hàng đợi vào Cloud Tasks cần có quyền sử dụng tài khoản dịch vụ được liên kết với một công việc trong Cloud Tasks.

    Trong mẫu, đây là tài khoản dịch vụ mặc định của App Engine.

Hãy xem Tài liệu về Google Cloud IAM để biết hướng dẫn về cách thêm tài khoản dịch vụ mặc định của App Engine làm người dùng của tài khoản dịch vụ mặc định của App Engine.

gcloud functions add-iam-policy-binding $FUNCTION_NAME \
  --region=us-central1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker