Cloud Tasks ile işlevleri sıraya alma


Görev sırası işlevleri, Google Cloud Görevleri Uygulamanızın zaman alan, kaynak yoğun veya bant genişliği sınırlı olarak çalıştırılmasına yardımcı olmak için ana uygulama akışınızın dışında eşzamansız olarak yapabilirsiniz.

Örneğin, geniş bir resim kümesinin yedeklerini oluşturmak istediğinizi Şu anda hız sınırı olan bir API'de barındırılan dosyalar. Bir insanın sorumlu tüketicisiyseniz, oran sınırlarına uymanız gerekir. Ayrıca, bu tür uzun süreli işler, zaman aşımları ve anlamına gelir.

Bu karmaşıklığı azaltmak için, Arkadaş Bitkiler projenizde kullanılabilecek temel scheduleTime ve dispatchDeadline gibi görev seçeneklerini ayarlayabilir, Cloud Tasks'ta bir sıraya göndermesini sağlar. Bulut Görevleri verimli bir şekilde tıkanıklık kontrolünü sağlamak ve yeniden deneme politikalarında bulunmayı unutmayın.

Cloud Functions for Firebase v3.20.1 ve üzeri sürümler için Firebase SDK'sı birlikte çalışır Firebase Admin SDK v10.2.0 ve sonraki sürümleri ile görev sırası işlevlerini desteklemek için.

Görev sırası işlevlerinin Firebase ile kullanılması, Cloud Tasks işleniyor. Görüntüleyin Cloud Tasks fiyatlandırması konulu videomuzu izleyin.

Görev sırası işlevleri oluşturma

Görev sırası işlevlerini kullanmak için şu iş akışını izleyin:

  1. Cloud Functions için Firebase SDK'sını kullanarak görev sırası işlevi yazın.
  2. İşlevinizi bir HTTP isteği ile tetikleyerek test edin.
  3. İşlevinizi Firebase CLI ile dağıtın. Görevinizi dağıtırken ilk kez kullanıyorsanız CLI, yeni bir Cloud Tasks'ta görev sırası seçenekleri (hız sınırlama ve yeniden deneme) kullanarak oluşturun.
  4. Yeni oluşturulan görev sırasına, ayarlamak için parametreleri ileterek görevleri ekleyin bir yürütme planı olabilir. Bunu, kodu yazarak Yönetici SDK'sını kullanıp Cloud Functions for Firebase'e dağıtabilirsiniz.

Görev sırası işlevlerini yazma

Bu bölümdeki kod örnekleri, NASA'nın kendi evindeki tüm görüntüleri yedekleyen bir hizmeti Günün Astronomi Resmi. Başlamak için gerekli modülleri içe aktarın:

Node.js

// Dependencies for task queue functions.
const {onTaskDispatched} = require("firebase-functions/v2/tasks");
const {onRequest, HttpsError} = require("firebase-functions/v2/https");
const {getFunctions} = require("firebase-admin/functions");
const {logger} = require("firebase-functions/v2");

// Dependencies for image backup.
const path = require("path");
const fetch = require("node-fetch");
const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const {GoogleAuth} = require("google-auth-library");

Python

# Dependencies for task queue functions.
from google.cloud import tasks_v2
import requests
from firebase_functions.options import RetryConfig, RateLimits, SupportedRegion

# Dependencies for image backup.
from datetime import datetime, timedelta
import json
import pathlib
from urllib.parse import urlparse
from firebase_admin import initialize_app, storage, functions
from firebase_functions import https_fn, tasks_fn, params
import google.auth
from google.auth.transport.requests import AuthorizedSession

onTaskDispatched kullanın veya on_task_dispatched fonksiyonları kullanabilirsiniz. Görev sırası işlevi yazarken sıra başına yeniden deneme ve hız sınırlaması yapılandırma ayarlayabilirsiniz.

Görev sırası işlevlerini yapılandırma

Görev sırası işlevleri, güçlü bir yapılandırma ayarı grubuyla birlikte gelir 'i kullanarak bir görev sırasının hız sınırlarını ve yeniden deneme davranışını hassas bir şekilde kontrol edebilirsiniz:

Node.js

exports.backupapod = onTaskDispatched(
    {
      retryConfig: {
        maxAttempts: 5,
        minBackoffSeconds: 60,
      },
      rateLimits: {
        maxConcurrentDispatches: 6,
      },
    }, async (req) => {

Python

@tasks_fn.on_task_dispatched(retry_config=RetryConfig(max_attempts=5, min_backoff_seconds=60),
                             rate_limits=RateLimits(max_concurrent_dispatches=10))
def backupapod(req: tasks_fn.CallableRequest) -> str:
    """Grabs Astronomy Photo of the Day (APOD) using NASA's API."""
  • retryConfig.maxAttempts=5: Görev sırasındaki her görev otomatik olarak en fazla 5 kez yeniden denendi. Bu, ağ gibi geçici hataları azaltmaya yardımcı olur bağımlı, harici bir hizmette hatalar veya geçici hizmet aksamaları olabilir.

  • retryConfig.minBackoffSeconds=60: Her görev en az 60 saniye sonra yeniden denenir hariç tutmanızı sağlar. Bu, her deneme arasında büyük bir tampon sağlar Dolayısıyla, 5 yeniden deneme hakkını çok hızlı bir şekilde bitirmek için acele etmeyiz.

  • rateLimits.maxConcurrentDispatch=6: En fazla 6 görev tek seferde dağıtılır yardımcı olabilir. Bu sayede, temel alınan kaynağa istikrarlı bir talep akışı sağlanabilir işlevi görebilir ve etkin örneklerin ve baştan başlatmaların sayısını azaltmaya yardımcı olur.

Görev sırası işlevlerini test etme

Firebase Local Emulator Suite'teki görev sırası işlevleri basit olarak gösterildi HTTP işlevleri. HTTP POST isteği göndererek emüle edilmiş bir görev işlevini test edebilirsiniz. JSON veri yüküyle istek:

 # 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

Görev sırası işlevlerini dağıtma

Görev sırası işlevini Firebase CLI kullanarak dağıtın:

$ firebase deploy --only functions:backupapod

Bir görev sırası işlevini ilk kez dağıtırken CLI, bir görev sırası işlevi Cloud Tasks'ta şu seçeneklere sahip görev sırası (hız sınırlama ve yeniden dene) kaynak kodunuzda belirtilir.

İşlevleri dağıtırken izin hatalarıyla karşılaşırsanız uygun IAM rollerini komutu, dağıtım komutlarını çalıştıran kullanıcıya atanır.

Görev sırası işlevlerini sıraya koyma

Görev sırası işlevleri, güvenilir bir kullanıcıdan Cloud Tasks'ta sıraya alınabilir Firebase Admin SDK'nın kullanıldığı Cloud Functions for Firebase gibi bir sunucu ortamı Python için Node.js veya Google Cloud kitaplıkları. Yönetici SDK'larını kullanmaya yeni başladıysanız bkz. Başlamak için Firebase'i bir sunucuya ekleyin.

Tipik bir akış yeni bir görev yaratır ve onu ve görev için yapılandırmayı belirler:

Node.js

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);
    });

Python

@https_fn.on_request()
def enqueuebackuptasks(_: https_fn.Request) -> https_fn.Response:
    """Adds backup tasks to a Cloud Tasks queue."""
    task_queue = functions.task_queue("backupapod")
    target_uri = get_function_url("backupapod")

    for i in range(BACKUP_COUNT):
        batch = i // HOURLY_BATCH_SIZE

        # Delay each batch by N hours
        schedule_delay = timedelta(hours=batch)
        schedule_time = datetime.now() + schedule_delay

        dispatch_deadline_seconds = 60 * 5  # 5 minutes

        backup_date = BACKUP_START_DATE + timedelta(days=i)
        body = {"data": {"date": backup_date.isoformat()[:10]}}
        task_options = functions.TaskOptions(schedule_time=schedule_time,
                                             dispatch_deadline_seconds=dispatch_deadline_seconds,
                                             uri=target_uri)
        task_queue.enqueue(body, task_options)
    return https_fn.Response(status=200, response=f"Enqueued {BACKUP_COUNT} tasks")
  • Örnek kod, yürütülebilecek verileri ve N’inci görev için N’inci dakika gecikmesini ilişkilendirerek görevleri tamamlayın. Bu Yaklaşık 1 görev/dakika tetikleme anlamına gelir. Şunu da deneyebilirsiniz: İsterseniz scheduleTime (Node.js) veya schedule_time (Python) Cloud Tasks'ı kullanabilirsiniz.

  • Örnek kod, kod sınırı olmadan Cloud Tasks bekleyecek tamamlanması gereken aktiviteleri ifade eder. Cloud Tasks yeniden denenecek yeniden denemenin ardından görev konfigürasyonunu kullanabilirsiniz. Örnekte, sıra, görevi en fazla 5 kez yeniden deneyecek şekilde yapılandırılmıştır ancak görev İşlemin tamamı (yeniden deneme denemeleri dahil) durumunda otomatik olarak iptal edilir 5 dakikadan fazla sürer.

Hedef URI'yı alma ve dahil etme

Cloud Tasks'ın kimlik doğrulama jetonları oluşturma yöntemi nedeniyle fonksiyonlarına ilişkin isteklerin yerine getirilmesini istiyorsanız Görevleri sıraya alırken işlevin Cloud Run URL'si. Biz işlevinizin URL'sini programlı bir şekilde gösterilmektedir:

Node.js

/**
 * 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;
}

Python

def get_function_url(name: str, location: str = SupportedRegion.US_CENTRAL1) -> str:
    """Get the URL of a given v2 cloud function.

    Params:
        name: the function's name
        location: the function's location

    Returns: The URL of the function
    """
    credentials, project_id = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"])
    authed_session = AuthorizedSession(credentials)
    url = ("https://cloudfunctions.googleapis.com/v2beta/" +
           f"projects/{project_id}/locations/{location}/functions/{name}")
    response = authed_session.get(url)
    data = response.json()
    function_url = data["serviceConfig"]["uri"]
    return function_url

Sorun giderme

Cloud Tasks günlük kaydını etkinleştir

Cloud Tasks günlükleri, şunun gibi yararlı teşhis bilgileri içerir: bir görevle ilişkili isteğin durumudur. Varsayılan olarak, Cloud Tasks, yüksek miktarda günlük kaydı olması nedeniyle devre dışı bırakıldı üzerinde etkisi olur. Hata ayıklama günlüklerini etkinleştirmenizi öneririz ve hata ayıklama işlemleri yürütürken sizi aktif olarak kilitleyin. Görüntüleyin Açılıyor günlük kaydı.

IAM İzinleri

Görevleri sıraya koyarken veyaPERMISSION DENIED Cloud Tasks, görev sırası işlevlerinizi çağırmaya çalışır. Araç açılış sayfalarınızla ilgili projede şu IAM bağlamaları bulunur:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudtasks.enqueuer
  • Görevleri Cloud Tasks'ta sıraya almak için kullanılan kimliğin izin alması gerekir Cloud Tasks'te bir görevle ilişkili hizmet hesabını kullanma

    Örnekte bu App Engine varsayılan hizmet hesabıdır.

Google Cloud IAM belgelerini inceleyin App Engine varsayılan hizmet hesabını ekleme talimatları için App Engine'in varsayılan hizmet hesabının kullanıcısı olarak ayarlandı.

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