Utiliser une file d'attente Cloud Tasks pour tamponner les exécutions de vos workflows

Ce tutoriel vous explique comment créer une file d'attente Cloud Tasks permettant de réguler la fréquence d'exécution des workflows.

Le nombre d'exécutions de workflow actives pouvant avoir lieu simultanément est limité. Une fois ce quota épuisé, et si le backlog d'exécution est désactivé ou si le quota d'exécutions en backlog est atteint, toute nouvelle exécution échoue avec un code d'état HTTP 429 Too many requests. En permettant à une file d'attente Cloud Tasks d'exécuter des workflows enfants à un rythme que vous définissez, vous pouvez éviter les problèmes liés aux quotas Workflows et obtenir un meilleur taux d'exécution.

Notez que Cloud Tasks est conçu pour fournir une exécution de type "au moins une fois". Toutefois, Workflows ne garantit pas le traitement exactement une fois des requêtes en double provenant de Cloud Tasks.

Dans le schéma suivant, un workflow parent appelle des workflows enfants qui sont régulés par une file d'attente Cloud Tasks à laquelle un taux de distribution est appliqué.

Workflow parent appelant des itérations d'un workflow enfant via une file d'attente Cloud Tasks

Créer une file d'attente Cloud Tasks

Créez une file d'attente Cloud Tasks que vous pouvez utiliser dans le workflow parent et qui vous permet de réguler le taux d'exécution des workflows.

Console

  1. Dans la console Google Cloud , accédez à la page Cloud Tasks :

    Accéder à Cloud Tasks

  2. Cliquez sur  > Créer une file d'attente d'envoi.

  3. Saisissez le nom de la file d'attente, queue-workflow-child.

  4. Dans la liste Région, sélectionnez us-central1 (Iowa).

  5. Cliquez sur Créer.

gcloud

QUEUE=queue-workflow-child
LOCATION=us-central1
gcloud tasks queues create $QUEUE --location=$LOCATION

Créer et déployer un workflow enfant

Un workflow enfant peut recevoir et traiter des données provenant d'un workflow parent. Créez et déployez un workflow enfant qui effectue les opérations suivantes :

  • Reçoit un iteration comme argument
  • Active la veille pendant 10 secondes pour simuler un traitement
  • Renvoie une chaîne en cas d'exécution réussie

Console

  1. Dans la console Google Cloud , accédez à la page Workflows.

    Accéder à "Workflows"

  2. Cliquez sur  Créer.

  3. Saisissez le nom du nouveau workflow, workflow-child.

  4. Dans la liste Région, sélectionnez us-central1 (Iowa).

  5. Dans la liste Compte de service, sélectionnez Compte de service Compute Engine par défaut.

  6. Cliquez sur Suivant.

  7. Dans l'éditeur de workflow, saisissez la définition suivante pour votre workflow :

    main:
      params: [args]
      steps:
        - init:
            assign:
              - iteration : ${args.iteration}
        - wait:
            call: sys.sleep
            args:
                seconds: 10
        - return_message:
            return: ${"Hello world"+iteration}
  8. Cliquez sur Déployer.

gcloud

  1. Créez un fichier de code source pour votre workflow :

    touch workflow-child.yaml
  2. Ouvrez votre fichier de code source dans un éditeur de texte et copiez-y le workflow suivant.

    main:
      params: [args]
      steps:
        - init:
            assign:
              - iteration : ${args.iteration}
        - wait:
            call: sys.sleep
            args:
                seconds: 10
        - return_message:
            return: ${"Hello world"+iteration}
  3. Déployez le workflow :

    gcloud workflows deploy workflow-child \
        --source=workflow-child.yaml \
        --location=us-central1 \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

Créer et déployer le workflow parent

Le workflow parent exécute plusieurs branches du workflow enfant à l'aide d'une boucle for.

  1. Copiez le code source qui définit le workflow parent :

    main:
      steps:
        - init:
            assign:
              - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
              - project_number: ${sys.get_env("GOOGLE_CLOUD_PROJECT_NUMBER")}
              - location: ${sys.get_env("GOOGLE_CLOUD_LOCATION")}
              - workflow_child_name: "workflow-child"
              - queue_name: "queue-workflow-child"
        - enqueue_tasks_to_execute_child_workflow:
            for:
              value: iteration
              range: [1, 100]
              steps:
                  - iterate:
                      assign:
                        - data:
                            iteration: ${iteration}
                        - exec:
                            # Encode object to JSON string in expression for workflow argument
                            argument: ${json.encode_to_string(data)}
                  - create_task_to_execute_child_workflow:
                      call: googleapis.cloudtasks.v2.projects.locations.queues.tasks.create
                      args:
                          parent: ${"projects/" + project_id + "/locations/" + location + "/queues/" + queue_name}
                          body:
                            task:
                              httpRequest:
                                body: ${base64.encode(json.encode(exec))}
                                url: ${"https://workflowexecutions.googleapis.com/v1/projects/" + project_id + "/locations/" + location + "/workflows/" + workflow_child_name + "/executions"}
                                oauthToken:
                                  serviceAccountEmail: ${project_number + "-compute@developer.gserviceaccount.com"}

    Le workflow se compose des parties suivantes :

    • Carte utilisée pour attribuer des constantes faisant référence au workflow enfant et au nom de la file d'attente Cloud Tasks. Pour en savoir plus, consultez Maps.

    • Boucle for exécutée pour appeler le workflow enfant de manière itérative. Pour en savoir plus, consultez la section Itération.

    • Étape de workflow qui crée et ajoute un grand nombre de tâches à la file d'attente Cloud Tasks pour exécuter le workflow enfant. Pour en savoir plus, consultez Connecteur de l'API Cloud Tasks.

  2. Déployez le workflow :

    Console

    1. Dans la console Google Cloud , accédez à la page Workflows :

      Accéder à "Workflows"

    2. Cliquez sur  Créer.

    3. Saisissez le nom du nouveau workflow, workflow-parent.

    4. Dans la liste Région, sélectionnez us-central1 (Iowa).

    5. Dans la liste Compte de service, sélectionnez Compte de service Compute Engine par défaut.

    6. Cliquez sur Suivant.

    7. Dans l'éditeur de workflow, collez la définition du workflow parent.

    8. Cliquez sur Déployer.

    gcloud

    1. Créez un fichier de code source pour votre workflow :

      touch workflow-parent.yaml
    2. Ouvrez votre fichier de code source dans un éditeur de texte et collez la définition du workflow parent.

    3. Déployez le workflow :

      gcloud workflows deploy workflow-parent \
          --source=workflow-parent.yaml \
          --location=us-central1 \
          --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

Exécuter le workflow parent sans limites de fréquence

Exécutez le workflow parent pour appeler les workflows enfants via la file d'attente Cloud Tasks. L'exécution devrait prendre environ 10 secondes.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Sur la page Workflows, cliquez sur le workflow workflow-parent pour accéder à sa page d'informations.

  3. Sur la page Détails du workflow, cliquez sur Exécuter.

  4. Cliquez à nouveau sur Exécuter.

  5. Pendant l'exécution du workflow parent, revenez à la page Workflows, puis cliquez sur le workflow workflow-child pour accéder à sa page d'informations.

  6. Cliquez sur l'onglet Exécutions.

    Vous devriez voir des exécutions du workflow enfant, qui s'exécutent à peu près en même temps, comme suit :

    Détails des exécutions de workflows enfants qui s'exécutent à peu près au même moment.

gcloud

  1. Exécutez le workflow :

    gcloud workflows run workflow-parent \
         --location=us-central1
  2. Pour vérifier qu'une exécution de workflow a été déclenchée, répertoriez les quatre dernières exécutions :

    gcloud workflows executions list workflow-child --limit=4

    Étant donné que le nombre d'exécutions (100) est inférieur à la limite de simultanéité des workflows, les résultats devraient ressembler à ce qui suit. Des problèmes de quota peuvent survenir si vous envoyez des milliers d'exécutions en même temps.

    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/1570d06e-d133-4536-a859-b7b6a1a85524
    STATE: ACTIVE
    START_TIME: 2023-07-27T00:56:15.093934448Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/82724960-7d92-4961-aa2c-a0f0be46212c
    STATE: ACTIVE
    START_TIME: 2023-07-27T00:56:14.903007626Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/598126fb-37f9-45bc-91d8-aea7d795d702
    STATE: ACTIVE
    START_TIME: 2023-07-27T00:56:14.698260524Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/d2e9960b-f93f-4df4-a594-3e7e5c2be53f
    STATE: ACTIVE
    START_TIME: 2023-07-27T00:56:14.503818840Z
    END_TIME: 

Vous avez créé et déployé un workflow qui appelle 100 itérations du workflow enfant.

Exécuter le workflow parent avec des limites de débit

Appliquez une limite de débit d'une distribution par seconde à la file d'attente Cloud Tasks, puis exécutez le workflow parent.

Console

  1. Dans la console Google Cloud , accédez à la page Cloud Tasks :

    Accéder à Cloud Tasks

  2. Cliquez sur queue-workflow-child, la file d'attente Cloud Tasks que vous avez créée, puis sur Modifier la file d'attente.

  3. Dans la section Limitation du débit pour les envois de tâches, saisissez 1 dans le champ Envois max.

  4. Cliquez sur Enregistrer.

  5. Accédez à la page Workflows :

    Accéder à "Workflows"

  6. Cliquez sur le workflow workflow-parent pour accéder à sa page d'informations.

  7. Sur la page Détails du workflow, cliquez sur Exécuter.

  8. Cliquez à nouveau sur Exécuter.

  9. Pendant l'exécution du workflow parent, revenez à la page Workflows, puis cliquez sur le workflow workflow-child pour accéder à sa page d'informations.

  10. Cliquez sur l'onglet Exécutions.

    Vous devriez voir des exécutions du workflow enfant, s'exécutant à une requête par seconde, comme suit :

    Détails du workflow enfant s'exécutant à la demande par seconde.

gcloud

  1. Mettez à jour la file d'attente Cloud Tasks pour appliquer une limite de débit d'une distribution par seconde :

    gcloud tasks queues update $QUEUE \
        --max-dispatches-per-second=1 \
        --location=us-central1
  2. Exécutez le workflow :

    gcloud workflows run workflow-parent \
       --location=us-central1
  3. Pour vérifier qu'une exécution de workflow a été déclenchée, répertoriez les quatre dernières exécutions :

    gcloud workflows executions list workflow-child --limit=4

    Les résultats doivent ressembler à ce qui suit, avec un workflow exécuté par seconde :

    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/becf4957-9fb2-40d9-835d-0ff2dd0c1249
    STATE: ACTIVE
    START_TIME: 2023-07-27T01:07:24.446361457Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/6c1e7c4b-7ac6-4121-b351-1e2d56d10903
    STATE: ACTIVE
    START_TIME: 2023-07-27T01:07:23.448213989Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/f2ba5027-af40-4cd3-8cd0-b8033bcc6211
    STATE: ACTIVE
    START_TIME: 2023-07-27T01:07:22.431485914Z
    END_TIME:
    NAME: projects/620278351741/locations/us-central1/workflows/workflow-child/executions/ecc61ee5-fe87-49eb-8803-89dba929f6c8
    STATE: ACTIVE
    START_TIME: 2023-07-27T01:07:21.443466369Z
    END_TIME: 

Vous avez déployé un workflow qui appelle 100 itérations du workflow enfant avec un taux de distribution d'une exécution par seconde.