Mengantrekan fungsi dengan Cloud Tasks

Fungsi task queue memanfaatkan Google Cloud Tasks untuk membantu aplikasi Anda menjalankan tugas yang memakan waktu, membutuhkan banyak resource, atau dibatasi bandwidth secara asinkron, di luar alur aplikasi utama Anda.

Misalnya, Anda ingin membuat cadangan untuk banyak kumpulan file gambar yang saat ini dihosting di API yang menerapkan pembatasan kapasitas. Untuk menjadi konsumen API yang bertanggung jawab, Anda perlu mematuhi batas kapasitasnya. Selain itu, pekerjaan jangka panjang semacam ini rentan mengalami kegagalan karena waktu tunggu habis dan batas memori.

Untuk mengurangi kompleksitas ini, Anda dapat menulis fungsi task queue yang menetapkan opsi tugas dasar seperti scheduleTime, dan dispatchDeadline, lalu melimpahkan fungsi tersebut ke antrean di Cloud Tasks. Lingkungan Cloud Tasks dirancang khusus untuk memastikan kontrol kemacetan dan kebijakan percobaan ulang yang efektif untuk jenis operasi ini.

Firebase SDK untuk Cloud Functions for Firebase v3.20.1 dan yang lebih tinggi memiliki interoperabilitas dengan Firebase Admin SDK v10.2.0 dan yang lebih tinggi untuk mendukung fungsi task queue.

Penggunaan fungsi task queue dengan Firebase dapat menyebabkan tagihan untuk pemrosesan Cloud Tasks. Baca artikel Harga Cloud Tasks untuk mengetahui informasi selengkapnya.

Membuat fungsi task queue

Untuk menggunakan fungsi task queue, ikuti alur kerja ini:

  1. Tulis fungsi task queue menggunakan Firebase SDK untuk Cloud Functions.
  2. Uji fungsi Anda menggunakan Firebase Local Emulator Suite.
  3. Deploy fungsi Anda dengan Firebase CLI. Saat men-deploy fungsi task queue untuk pertama kalinya, CLI akan membuat task queue di Cloud Tasks dengan opsi (pembatasan kapasitas dan percobaan ulang) yang ditentukan dalam kode sumber Anda.
  4. Tambahkan tugas ke task queue yang baru dibuat, dengan meneruskan parameter untuk menyiapkan jadwal eksekusi jika diperlukan. Anda dapat mencapainya dengan menulis kode menggunakan Admin SDK dan men-deploy-nya ke Cloud Functions for Firebase.

Menulis fungsi task queue

Gunakan onTaskDispatched untuk mulai menulis fungsi task queue. Bagian penting dari penulisan fungsi task queue adalah menetapkan percobaan ulang per antrean dan konfigurasi pembatasan kapasitas. Contoh kode di halaman ini didasarkan pada aplikasi yang menyiapkan layanan yang mencadangkan semua gambar dari Astronomy Picture of the Day milik NASA:

Konfigurasi task queue

Fungsi task queue dilengkapi dengan kumpulan setelan konfigurasi yang canggih untuk mengontrol secara akurat batas kapasitas dan perilaku percobaan ulang task queue:

exports.backupapod = onTaskDispatched(
    {
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }, async (req) => {
  • retryConfig.maxAttempts=5: Setiap tugas di task queue otomatis dicoba ulang hingga 5 kali. Hal ini membantu mengurangi error sementara seperti error jaringan atau gangguan layanan sementara dari layanan eksternal yang dependen.
  • retryConfig.minBackoffSeconds=60: Setiap tugas dicoba ulang dengan interval antarpercobaan minimal 60 detik. Hal ini memberikan buffer besar di antara setiap percobaan sehingga batas 5 kali percobaan tidak akan terlalu cepat habis.
  • rateLimits.maxConcurrentDispatch=6: Maksimal 6 tugas dikirim secara bersamaan. Hal ini membantu memastikan aliran permintaan yang stabil ke fungsi yang mendasarinya serta membantu mengurangi jumlah instance aktif dan cold start.

Menguji fungsi task queue menggunakan Firebase Local Emulator Suite

Fungsi task queue di Firebase Local Emulator Suite diekspos sebagai fungsi HTTP sederhana. Anda dapat menguji fungsi tugas yang diemulasi dengan mengirimkan permintaan HTTP POST dengan payload data json:

 # start the Local Emulator Suite
 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

Men-deploy fungsi task queue

Deploy fungsi task queue menggunakan Firebase CLI:

$ firebase deploy --only functions:backupapod

Saat men-deploy fungsi task queue untuk pertama kalinya, CLI akan membuat task queue di Cloud Tasks dengan opsi (pembatasan kapasitas dan percobaan ulang) yang ditentukan dalam kode sumber Anda.

Jika Anda mengalami error izin saat men-deploy fungsi, pastikan peran IAM yang sesuai ditetapkan kepada pengguna yang menjalankan perintah deployment.

Mengantrekan fungsi

Fungsi task queue dapat diantrekan di Cloud Tasks dari lingkungan server tepercaya seperti Cloud Functions for Firebase menggunakan Firebase Admin SDK untuk Node.js. Jika Anda baru pertama kali menggunakan Admin SDK, baca artikel Menambahkan Firebase ke server untuk memulai.

Pada alur standar, Admin SDK membuat tugas baru, mengantrekannya di Cloud Tasks, dan menetapkan konfigurasi untuk tugas tersebut:

exports.enqueuebackuptasks = onRequest(
    async (_request, response) => {
      const queue = getFunctions().taskQueue("backupapod");
      const targetUri = await getFunctionUrl("backupapod");

      const enqueues = [];
      for (let i = 0; i <= BACKUP_COUNT; i += 1) {
        const iteration = Math.floor(i / HOURLY_BATCH_SIZE);
        // Delay each batch by N * hour
        const scheduleDelaySeconds = iteration * (60 * 60);

        const backupDate = new Date(BACKUP_START_DATE);
        backupDate.setDate(BACKUP_START_DATE.getDate() + i);
        // Extract just the date portion (YYYY-MM-DD) as string.
        const date = backupDate.toISOString().substring(0, 10);
        enqueues.push(
            queue.enqueue({date}, {
              scheduleDelaySeconds,
              dispatchDeadlineSeconds: 60 * 5, // 5 minutes
              uri: targetUri,
            }),
        );
      }
      await Promise.all(enqueues);
      response.sendStatus(200);
    });
  • scheduleDelaySeconds: Kode contoh mencoba menyebarkan eksekusi tugas dengan mengaitkan penundaan menit ke-N untuk tugas ke-N. Hal ini akan memicu ~ 1 tugas/menit. Perlu diperhatikan bahwa Anda juga dapat menggunakan scheduleTime jika ingin Cloud Tasks memicu tugas pada waktu tertentu.
  • dispatchDeadlineSeconds: Jumlah maksimum waktu Cloud Tasks akan menunggu hingga tugas selesai. Cloud Tasks akan mencoba kembali tugas ini setelah konfigurasi percobaan ulang antrean atau sampai batas waktu ini tercapai. Dalam contoh, antrean dikonfigurasi untuk mencoba ulang tugas hingga 5 kali, tetapi tugas tersebut akan otomatis dibatalkan jika seluruh proses (termasuk upaya percobaan ulang) memerlukan waktu lebih dari 5 menit.

Mengambil dan menyertakan URI target

Terkait cara Cloud Tasks membuat token autentikasi untuk mengautentikasi permintaan pada fungsi task queue yang mendasarinya, Anda harus menentukan URL Cloud Run dari fungsi tersebut saat mengantrekan tugas. Sebaiknya Anda mengambil URL secara terprogram untuk fungsi Anda seperti yang ditunjukkan di bawah:

/**
 * Get the URL of a given v2 cloud function.
 *
 * @param {string} name the function's name
 * @param {string} location the function's location
 * @return {Promise<string>} The URL of the function
 */
async function getFunctionUrl(name, location="us-central1") {
  if (!auth) {
    auth = new GoogleAuth({
      scopes: "https://www.googleapis.com/auth/cloud-platform",
    });
  }
  const projectId = await auth.getProjectId();
  const url = "https://cloudfunctions.googleapis.com/v2beta/" +
    `projects/${projectId}/locations/${location}/functions/${name}`;

  const client = await auth.getClient();
  const res = await client.request({url});
  const uri = res.data?.serviceConfig?.uri;
  if (!uri) {
    throw new Error(`Unable to retreive uri for function at ${url}`);
  }
  return uri;
}

Pemecahan masalah

Mengaktifkan logging Cloud Tasks

Log dari Cloud Tasks berisi informasi diagnostik yang berguna, seperti status permintaan yang terkait dengan tugas. Secara default, log dari Cloud Tasks dinonaktifkan karena banyaknya log yang dapat dihasilkan di project Anda. Sebaiknya aktifkan log debug saat Anda aktif mengembangkan dan men-debug fungsi task queue Anda. Baca artikel Mengaktifkan logging.

Izin IAM

Anda mungkin melihat error PERMISSION DENIED saat mengantrekan tugas atau saat Cloud Tasks mencoba memanggil fungsi task queue Anda. Pastikan project Anda memiliki binding IAM berikut:

  • Identitas yang digunakan untuk mengantrekan tugas ke Cloud Tasks memerlukan izin IAM cloudtasks.tasks.create.

    Dalam contoh, hal ini adalah akun layanan default App Engine

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Identitas yang digunakan untuk mengantrekan tugas ke Cloud Tasks memerlukan izin untuk menggunakan akun layanan yang terkait dengan tugas di Cloud Tasks.

    Dalam contoh, hal ini adalah akun layanan default App Engine.

Baca dokumentasi Google Cloud IAM untuk mengetahui petunjuk mengenai cara menambahkan akun layanan default App Engine sebagai pengguna akun layanan default App Engine.

  • Identitas yang digunakan untuk memicu fungsi task queue memerlukan izin cloudfunctions.functions.invoke.

    Dalam contoh, hal ini adalah akun layanan default App Engine

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