Best practice per Workflows

Per l'orchestrazione dei tuoi servizi, puoi consultare le best practice elencate qui utilizzando Workflows.

Questo non è un elenco completo di consigli e non fornisce informazioni le nozioni di base sull'utilizzo di Workflows. In questo documento si presuppone che tu hanno già una conoscenza generale del panorama complessivo di Google Cloud di Workflows. Per ulteriori informazioni, consulta Framework dell'architettura Google Cloud e Panoramica dei flussi di lavoro.

Seleziona un modello di comunicazione ottimale

Quando si progetta un'architettura di microservizi per il deployment di più servizi, puoi scegliere tra i seguenti modelli di comunicazione:

  • Comunicazione diretta tra servizi

  • Comunicazione indiretta basata su eventi (nota anche come coreografia)

  • Configurazione, coordinamento e gestione automatizzate (note anche come orchestrazione)

Assicuratevi di considerare i vantaggi e gli svantaggi di ciascuno dei prodotti e selezionare un pattern ottimale per il tuo caso d'uso. Ad esempio, accesso diretto la comunicazione tra servizi potrebbe essere più semplice da implementare rispetto ad altre ma è strettamente collegato ai tuoi servizi. Al contrario, un'architettura basata su eventi consente accoppi i servizi a breve termine, tuttavia, il monitoraggio e il debug più complicata. Infine, un agente di orchestrazione centrale come Workflows, mentre meno flessibile, consente di coordinare la comunicazione tra i servizi senza il stretto binomio della comunicazione diretta tra servizi o la complessità di eventi coreografati.

Puoi anche combinare modelli di comunicazione. Ad esempio, nel caso di modelli dell'orchestrazione, i servizi strettamente correlati sono gestiti in un'orchestrazione attivati da un evento. Analogamente, potresti progettare un sistema in cui un'orchestrazione risulta in un messaggio Pub/Sub a un altro orchestrato.

Suggerimenti di carattere generale

Una volta deciso di usare Workflows come agente di orchestrazione dei servizi, tieni a mente questi utili suggerimenti.

Evita l'impostazione di URL come hardcoded

Puoi supportare flussi di lavoro portabili in più ambienti e più facile da gestire evitando gli URL impostati come hardcoded. Puoi farlo nel nei seguenti modi:

  • Definisci gli URL come argomenti di runtime.

    Ciò può essere utile quando il flusso di lavoro viene richiamato tramite una libreria client o l'API. (Tuttavia, questa operazione non funziona se il flusso di lavoro viene attivato un evento da Eventarc e l'unico argomento che può essere passato è il payload dell'evento.)

    Esempio

    main:
      params: [args]
      steps:
        - init:
            assign:
              - url1: ${args.urls.url1}
              - url2: ${args.urls.url2}

    Quando esegui il flusso di lavoro, puoi specificare gli URL. Ad esempio:

    gcloud workflows run multi-env --data='{"urls":{"url1": "URL_ONE", "url2": "URL_TWO"}}'
  • Utilizza le variabili di ambiente e crea un flusso di lavoro configurato dinamicamente in base all'ambiente in cui viene eseguito il deployment. In alternativa, crea un flusso di lavoro che possa essere riutilizzato come modello e configurato in base a un ambiente gestito separatamente come la codifica one-hot delle variabili categoriche.

  • Utilizzare una tecnica di sostituzione che consente di creare un singolo flusso di lavoro file di definizione, ma esegui il deployment delle varianti usando uno strumento che sostituisce i segnaposto nel tuo flusso di lavoro. Ad esempio, puoi utilizzare Cloud Build per eseguire il deployment di un flusso di lavoro e, nel file di configurazione di Cloud Build, aggiungere per sostituire gli URL segnaposto nel flusso di lavoro.

    Esempio

    steps:
    ‐ id: 'replace-urls'
      name: 'gcr.io/cloud-builders/gcloud'
      entrypoint: bash
      args:
        - -c
        - |
          sed -i -e "s~REPLACE_url1~$_URL1~" workflow.yaml
          sed -i -e "s~REPLACE_url2~$_URL2~" workflow.yaml
    ‐ id: 'deploy-workflow'
      name: 'gcr.io/cloud-builders/gcloud'
      args: ['workflows', 'deploy', 'multi-env-$_ENV', '--source', 'workflow.yaml']

    Dopodiché puoi sostituisci i valori delle variabili al momento della creazione. Ad esempio:

    gcloud builds submit --config cloudbuild.yaml \
        --substitutions=_ENV=staging,_URL1="URL_ONE",_URL2="URL_TWO"

    Per ulteriori informazioni, vedi Invia una build tramite interfaccia a riga di comando e API.

    In alternativa, puoi utilizzare Terraform eseguire il provisioning dell'infrastruttura e definire un file di configurazione crea flussi di lavoro per ogni ambiente utilizzando variabili di input.

    Esempio

    variable "project_id" {
      type = string
    }
    
    variable "url1" {
      type = string
    }
    
    variable "url2" {
      type = string
    }
    
    locals {
      env = ["staging", "prod"]
    }
    
    # Define and deploy staging and production workflows
    resource "google_workflows_workflow" "multi-env-workflows" {
      for_each = toset(local.env)
    
      name            = "multi-env-${each.key}"
      project         = var.project_id
      region          = "us-central1"
      source_contents = templatefile("${path.module}/workflow.yaml", { url1 : "${var.url1}-${each.key}", url2 : "${var.url2}-${each.key}" })
    }

    Quando le variabili vengono dichiarate nel modulo principale della configurazione, possono essere valori assegnati in vari modi. Ad esempio:

    terraform apply -var="project_id=PROJECT_ID" -var="url1=URL_ONE" -var="url2=URL_TWO"
  • Utilizzare il connettore Secret Manager per archiviare in modo sicuro gli URL in Secret Manager e recuperarli.

Utilizzare passaggi nidificati

Ogni flusso di lavoro deve includere almeno un passaggio. Per impostazione predefinita, Workflows tratta i passaggi come se fossero in un ordine ed esegue i passaggi uno alla volta finché non sono stati eseguiti tutti i passaggi. A livello logico, alcuni passaggi dovrebbero essere raggruppati e puoi utilizzare un blocco steps per nidificare di passaggi. Questo è conveniente perché ti consente di puntare alla porzione atomica corretta per elaborare una serie di passaggi.

Esempio

main:
    params: [input]
    steps:
    - callWikipedia:
        steps:
        - checkSearchTermInInput:
            switch:
                - condition: ${"searchTerm" in input}
                  assign:
                    - searchTerm: ${input.searchTerm}
                  next: readWikipedia
        - getCurrentDate:
            call: http.get
            args:
                url: https://timeapi.io/api/Time/current/zone?timeZone=Europe/Amsterdam
            result: currentDate
        - setFromCallResult:
            assign:
                - searchTerm: ${currentDate.body.dayOfWeek}
        - readWikipedia:
            call: http.get
            args:
                url: https://en.wikipedia.org/w/api.php
                query:
                    action: opensearch
                    search: ${searchTerm}
            result: wikiResult
    - returnOutput:
            return: ${wikiResult.body[1]}

Aggrega espressioni

Tutte le espressioni devono iniziare con a $ e devono essere racchiuse tra parentesi graffe:

${EXPRESSION}

Per evitare problemi di analisi YAML, puoi racchiudere le espressioni tra virgolette. Ad esempio: espressioni contenenti due punti possono causare comportamenti imprevisti quando i due punti vengono interpretati come il riferimento di una mappa. Puoi risolvere questo problema racchiudendo l'espressione YAML tra virgolette singole:

'${"Name: " + myVar}'

Puoi anche utilizzare espressioni che si estendono su più righe. Ad esempio, potresti aggregare una query SQL tra virgolette quando si utilizza il Workflows connettore BigQuery.

Esempio

- runQuery:
    call: googleapis.bigquery.v2.jobs.query
    args:
        projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
        body:
            useLegacySql: false
            useQueryCache: false
            timeoutMs: 30000
            # Find top 100 titles with most views on Wikipedia
            query: ${
                "SELECT TITLE, SUM(views)
                FROM `bigquery-samples.wikipedia_pageviews." + table + "`
                WHERE LENGTH(TITLE) > 10
                GROUP BY TITLE
                ORDER BY SUM(VIEWS) DESC
                LIMIT 100"
                }
    result: queryResult

Per l'intera definizione del flusso di lavoro, consulta Esegui più job BigQuery in parallelo.

Utilizza chiamate dichiarative

Utilizzare Workflows per chiamare i servizi dal flusso di lavoro stesso gestire i risultati ed eseguire semplici attività come effettuando una chiamata HTTP. Workflows può richiamare servizi, analizzare risposte costruire input per altri servizi connessi. Chiamare un servizio consente di evitare le complicazioni di chiamate extra, di dipendenze aggiuntive e servizi che chiamano servizi. Valuta la possibilità di sostituire privi di logica di business con chiamate API dichiarative e Workflows per astrarre la complessità.

Tuttavia, devi creare servizi per svolgere le attività troppo complesse for Workflows; ad esempio implementando una logica di business riutilizzabile, calcoli complessi o trasformazioni non supportate Espressioni di Workflows e relativa libreria standard. Un caso complicato è generalmente più facile da implementare nel codice, anziché utilizzare YAML o JSON e la sintassi di Workflows.

Archivia solo ciò che ti serve

Tieni sotto controllo il consumo della memoria in modo da non dover limiti delle risorse o un errore che indica come ResourceLimitError, MemoryLimitExceededError o ResultSizeLimitExceededError.

Scegli con cura ciò che archivi variabili, filtrando e per archiviare solo ciò che serve. Se un servizio restituisce un payload troppo grande, utilizzare una funzione separata per effettuare la chiamata per te e restituire solo ciò che è necessario.

Puoi liberare memoria cancellando le variabili. Ad esempio, puoi decidere di liberare necessaria per i passaggi successivi. Potresti anche avere chiamate con risultati che non ti interessano e puoi ometterli del tutto.

Puoi cancellare una variabile assegnando null. In YAML, puoi anche assegnare valore vuoto o ~ a una variabile. Questo identifica la memoria che può essere rivendicato.

Esempio

  - step:
      assign:
        - bigVar:

Utilizzare flussi di lavoro secondari e esterni

Puoi utilizzare flussi di lavoro secondari per definisci una parte della logica o un insieme di passaggi da chiamare più volte, semplificando la definizione del flusso di lavoro. I flussi di lavoro secondari sono simili a una funzione in un linguaggio di programmazione. Può accettare parametri e restituire valori, consentendoti di creare flussi di lavoro più complessi con una gamma più ampia di applicazioni.

Tieni presente che i flussi di lavoro secondari sono locali rispetto alla definizione del flusso di lavoro e non possono essere riutilizzati in altri flussi di lavoro. Tuttavia, puoi chiamare flussi di lavoro da altri flussi di lavoro. I connettori Workflows possono aiutarti. Per ulteriori informazioni informazioni, consulta le panoramiche dei connettori per API Workflow Executions e l'API Workflows.

Utilizzo dei connettori di Workflows

Workflows offre diversi connettori che semplificano per accedere ad altri prodotti Google Cloud all'interno di un flusso di lavoro. Connettori semplificare i servizi di chiamata perché gestiscono la formattazione delle richieste per te, fornendo metodi e argomenti in modo che non sia necessario conoscere i dettagli l'API Google Cloud. I connettori hanno anche un comportamento integrato per la gestione tentativi e operazioni a lunga esecuzione per evitare l'iterazione delle chiamate e il loro completamento; i connettori si occupano di questo aspetto.

Se devi chiamare un'API Google Cloud, verifica innanzitutto se Il connettore Workflows per il quale esiste. E se non vedi un per un prodotto Google Cloud, puoi richiedila.

Scopri come utilizzare un connettore e, per un riferimento dettagliato ai connettori disponibili, consulta Informazioni sui connettori.

Esegui i passaggi del flusso di lavoro in parallelo

Sebbene Workflows possa eseguire i passaggi in sequenza, è possibile passaggi indipendenti in parallelo. In alcuni casi, questa operazione può velocizzare notevolmente l'esecuzione del flusso di lavoro. Per ulteriori informazioni, vedi Esegui i passaggi del flusso di lavoro in parallelo.

Applicare i nuovi tentativi e il pattern saga

Progettare flussi di lavoro resilienti e in grado di gestire flussi di lavoro temporanei e permanenti degli errori del servizio. Gli errori relativi a Workflows possono essere generati, ad esempio, da richieste HTTP, funzioni, connettori non riusciti o generati dal tuo flusso di lavoro le API nel tuo codice. Aggiungi la gestione degli errori e i nuovi tentativi in modo che un errore in un passaggio non causi l'intero flusso di lavoro non riuscirà.

Alcune transazioni aziendali comprendono più servizi, quindi è necessario un meccanismo per a implementare le transazioni che riguardano i servizi. Il pattern di design della saga è un modo gestire la coerenza dei dati tra microservizi in scenari di transazioni distribuite. Una saga è una sequenza di transazioni che pubblica un evento per ogni della transazione e che attiva la transazione successiva. Se una transazione non va a buon fine, saga esegue transazioni di compensazione che compensano gli errori precedenti nella sequenza. Prova la Tutorial sui nuovi tentativi e sui pattern Saga in Workflows su GitHub.

Utilizza i callback per attendere

Flusso di lavoro delle autorizzazioni per i callback delle esecuzioni in attesa che un altro servizio effettui una richiesta endpoint di callback; che la richiesta riprende l'esecuzione del flusso di lavoro.

Con i callback, puoi segnalare al tuo flusso di lavoro che un evento specifico è si è verificato e attendere l'evento senza effettuare un polling. Ad esempio, puoi creare un flusso di lavoro per ricevere una notifica quando un prodotto è di nuovo disponibile disponibile o quando un articolo è stato spedito o che attende di consentire l'interazione umana come la revisione di un ordine o la convalida di una traduzione. Puoi anche attendere eventi utilizzando callback e trigger Eventarc.

Orchestra job a lunga esecuzione

Se devi eseguire query a lunga esecuzione elaborazione batch carichi di lavoro, puoi utilizzare Batch job Cloud Run e puoi utilizzare Workflows per la gestione dei servizi. In questo modo puoi combinare vantaggi ed efficiente il provisioning e l'orchestrazione dell'intero processo.

Batch è un servizio completamente gestito che ti consente pianificare, inserire in coda ed eseguire carichi di lavoro batch sulla di Compute Engine (VM). Puoi utilizzare lo Connettore Workflows per Batch per pianificare ed eseguire un job batch. Per maggiori dettagli, prova il tutorial.

I job Cloud Run vengono utilizzati per eseguire il codice che esegue il lavoro (un job) e si chiude al termine del lavoro. Workflows ti consente di eseguire Job Cloud Run nell'ambito di un flusso di lavoro per eseguire dati più complessi per l'elaborazione o l'orchestrazione di un sistema di job esistenti. Prova il tutorial, ovvero illustra come utilizzare Workflows per eseguire del job Cloud Run.

Containerizza le attività di lunga durata

Puoi automatizzare l'esecuzione di un container a lunga esecuzione utilizzando Workflows e Compute Engine. Ad esempio, puoi containerizzare un'attività a lunga esecuzione in modo che possa essere eseguita ovunque, quindi container su una VM di Compute Engine per la durata massima di un flusso di lavoro di esecuzione (un anno).

Con Workflows, puoi automatizzare la creazione della VM, del container sulla VM e l'eliminazione della VM. Questo consente di usare un server ed eseguire un container, ma astrae la complessità gestire entrambi e può essere utile se riscontri limiti di tempo quando utilizzi un servizio come Cloud Functions o Cloud Run. Prova la Container a lunga esecuzione con Workflows e Compute Engine su GitHub.

Esecuzione di strumenti a riga di comando da Workflows

Cloud Build è un servizio che esegue le tue build su Google Cloud come una serie di passaggi di build, dove ogni passaggio viene eseguito in container Docker. L'esecuzione di passaggi di build è analoga all'esecuzione di comandi in una lo script.

Google Cloud CLI include gcloud, bq e kubectl strumenti a riga di comando ma non esiste un modo diretto per eseguire gcloud CLI da Workflows. Tuttavia, Cloud Build fornisce immagini container che includono gcloud CLI. Puoi eseguire i comandi gcloud CLI in questi container da un Cloud Build ed eseguire il passaggio per crearlo in Workflows utilizzando Connettore Cloud Build.

Esempio

Esegui gcloud in un flusso di lavoro:

# This example shows how to execute gcloud commands from Workflows
# using Cloud Build and returns the output

main:
  steps:
  - execute_command:
      call: gcloud
      args:
          args: "workflows list"
      result: result
  - return_result:
      return: ${result}

gcloud:
  params: [args]
  steps:
  - create_build:
      call: googleapis.cloudbuild.v1.projects.builds.create
      args:
        projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
        parent: ${"projects/" + sys.get_env("GOOGLE_CLOUD_PROJECT_ID") + "/locations/global"}
        body:
          serviceAccount: ${sys.get_env("GOOGLE_CLOUD_SERVICE_ACCOUNT_NAME")}
          options:
            logging: CLOUD_LOGGING_ONLY
          steps:
          - name: gcr.io/google.com/cloudsdktool/cloud-sdk
            entrypoint: /bin/bash
            args: ${["-c", "gcloud " + args + " > $$BUILDER_OUTPUT/output"]}
      result: result_builds_create
  - return_build_result:
      return: ${text.split(text.decode(base64.decode(result_builds_create.metadata.build.results.buildStepOutputs[0])), "\n")}

Run kubectl in a workflow:

# This example shows how to execute kubectl commands from Workflows
# using Cloud Build and returns the output

main:
  steps:
  - execute_command:
      call: kubectl
      args:
          args: "--help"
      result: result
  - return_result:
      return: ${result}

kubectl:
  params: [args]
  steps:
  - create_build:
      call: googleapis.cloudbuild.v1.projects.builds.create
      args:
        projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
        parent: ${"projects/" + sys.get_env("GOOGLE_CLOUD_PROJECT_ID") + "/locations/global"}
        body:
          serviceAccount: ${sys.get_env("GOOGLE_CLOUD_SERVICE_ACCOUNT_NAME")}
          options:
            logging: CLOUD_LOGGING_ONLY
          steps:
          - name: gcr.io/cloud-builders/kubectl
            entrypoint: /bin/bash
            args: ${["-c", "kubectl " + args + " > $$BUILDER_OUTPUT/output"]}
      result: result_builds_create
  - return_build_result:
      return: ${text.split(text.decode(base64.decode(result_builds_create.metadata.build.results.buildStepOutputs[0])), "\n")}

Utilizzare Terraform per creare il flusso di lavoro

Terraform è uno strumento Infrastructure as Code che ti consente di creare, modificare e migliorare in modo prevedibile la tua infrastruttura cloud utilizzando il codice.

Puoi definire ed eseguire il deployment di un flusso di lavoro utilizzando google_workflows_workflow risorsa. Per ulteriori informazioni, vedi Crea un flusso di lavoro utilizzando Terraform.

Per gestire e mantenere flussi di lavoro di grandi dimensioni, puoi creare un flusso di lavoro in un file YAML separato e importarlo in Terraform utilizzando Funzione templatefile che legge un file in un determinato percorso e ne esegue il rendering come modello.

Esempio

  # Define a workflow
  resource "google_workflows_workflow" "workflows_example" {
    name            = "sample-workflow"
    region          = var.region
    description     = "A sample workflow"
    service_account = google_service_account.workflows_service_account.id
    # Import main workflow YAML file
    source_contents = templatefile("${path.module}/workflow.yaml",{})
  }

Analogamente, se un flusso di lavoro principale chiama più flussi di lavoro secondari, definire il flusso di lavoro principale e i flussi di lavoro secondari in file separati e utilizzare templatefile per importarle.

Esempio

  # Define a workflow
  resource "google_workflows_workflow" "workflows_example" {
    name            = "sample-workflow"
    region          = var.region
    description     = "A sample workflow"
    service_account = google_service_account.workflows_service_account.id
    # Import main workflow and subworkflow YAML files
    source_contents = join("", [
      templatefile(
        "${path.module}/workflow.yaml",{}
      ),

      templatefile(
        "${path.module}/subworkflow.yaml",{}
      )])
  }

Tieni presente che se fai riferimento ai numeri di riga durante il debug di un flusso di lavoro, tutte le I file YAML importati tramite il file di configurazione Terraform vengono uniti il deployment in un unico flusso di lavoro.

Esegui il deployment di un flusso di lavoro da un repository Git

Cloud Build utilizza trigger di build per abilitare l'automazione CI/CD. Puoi configurare trigger per l'ascolto degli eventi in arrivo, ad esempio quando viene richiesto un nuovo commit il push a un repository o all'avvio di una richiesta di pull esegue automaticamente una build quando arrivano nuovi eventi.

Puoi utilizzare un trigger di Cloud Build per avviare automaticamente una build ed eseguire il deployment di un flusso di lavoro da un repository Git. Puoi configurare il trigger eseguire il deployment del flusso di lavoro per qualsiasi modifica al repository di origine oppure solo se la modifica corrisponde a criteri specifici.

Questo approccio può aiutarti a gestire il ciclo di vita del deployment. Ad esempio, può eseguire il deployment delle modifiche a un flusso di lavoro in un ambiente di gestione temporanea, eseguire test quell'ambiente per poi lanciare in modo incrementale queste modifiche nell'ambiente di produzione. Per ulteriori informazioni, vedi Esegui il deployment di un flusso di lavoro da un repository Git utilizzando Cloud Build.

Ottimizza l'utilizzo

Il costo per l'esecuzione di un flusso di lavoro è minimo. Tuttavia, per una maggiore per l'utilizzo del volume, applica le seguenti linee guida per ottimizzare l'utilizzo e ridurre i costi:

  • Anziché utilizzare domini personalizzati, assicurati che tutte le chiamate a Google Cloud utilizzano *.appspot.com, *.cloud.goog, *.cloudfunctions.net o *.run.app in modo che ti vengano addebitati i costi per i passaggi interni e non esterni.

  • Applicare un criterio personalizzato per i nuovi tentativi che bilancia le tue esigenze di latenza e affidabilità con i costi. Più frequente riprova a ridurre la latenza e aumenta l'affidabilità, ma può anche far aumentare i costi.

  • Se utilizzi connettori in attesa di operazioni a lunga esecuzione, imposta un valore criterio di sondaggio personalizzato che ottimizza la latenza in termini di costi. Ad esempio, se prevedi che un'operazione in un'ora, ti consigliamo di creare un criterio che inizialmente esegue il polling dopo un minuto in caso di errore immediato e poi ogni 15 minuti in seguito.

  • Combinare i compiti in un solo passaggio.

  • Evita l'uso eccessivo di sys.log passaggi. Valuta l'uso registrazione delle chiamate.

Riepilogo delle best practice

La seguente tabella riassume i suggerimenti generali e le best practice consigliati in questo documento.

Suggerimenti di carattere generale
Best practice

Passaggi successivi