Desenvolver e criar um job do Go no Cloud Run

Aprenda a criar um job simples do Cloud Run e implantar a partir da origem, o que empacota automaticamente seu código em uma imagem de contêiner, faz upload da imagem do contêiner para o Artifact Registry e implanta no Cloud Run. É possível usar outras linguagens além das mostradas.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Make sure that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Ative a API Cloud Run Admin:

    gcloud services enable run.googleapis.com
    

    Depois que a API Cloud Run Admin for ativada, a conta de serviço padrão do Compute Engine será criadas automaticamente.

  11. Para que o Cloud Build consiga criar suas origens, conceda o papel Conta de serviço do Cloud Build para a conta de serviço padrão do Compute Engine. Basta executar o comando a seguir:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --role=roles/cloudbuild.builds.builder
    

    Substitua PROJECT_NUMBER pelo número do projeto do Google Cloud e PROJECT_ID pelo ID do projeto do Google Cloud.

    O número e o ID do projeto estão disponíveis na página Olá! do console do Google Cloud.

Como escrever o job de amostra

Para gravar um job no Go, faça o seguinte:

  1. Crie um novo diretório com o nome jobs e altere o diretório nele:

    mkdir jobs
    cd jobs
    
  2. No mesmo diretório, crie um arquivo main.go para o código do job real. Copie as seguintes linhas de amostra:

    package main
    
    import (
    	"fmt"
    	"log"
    	"math/rand"
    	"os"
    	"strconv"
    	"time"
    )
    
    type Config struct {
    	// Job-defined
    	taskNum    string
    	attemptNum string
    
    	// User-defined
    	sleepMs  int64
    	failRate float64
    }
    
    func configFromEnv() (Config, error) {
    	// Job-defined
    	taskNum := os.Getenv("CLOUD_RUN_TASK_INDEX")
    	attemptNum := os.Getenv("CLOUD_RUN_TASK_ATTEMPT")
    	// User-defined
    	sleepMs, err := sleepMsToInt(os.Getenv("SLEEP_MS"))
    	failRate, err := failRateToFloat(os.Getenv("FAIL_RATE"))
    
    	if err != nil {
    		return Config{}, err
    	}
    
    	config := Config{
    		taskNum:    taskNum,
    		attemptNum: attemptNum,
    		sleepMs:    sleepMs,
    		failRate:   failRate,
    	}
    	return config, nil
    }
    
    func sleepMsToInt(s string) (int64, error) {
    	sleepMs, err := strconv.ParseInt(s, 10, 64)
    	return sleepMs, err
    }
    
    func failRateToFloat(s string) (float64, error) {
    	// Default empty variable to 0
    	if s == "" {
    		return 0, nil
    	}
    
    	// Convert string to float
    	failRate, err := strconv.ParseFloat(s, 64)
    
    	// Check that rate is valid
    	if failRate < 0 || failRate > 1 {
    		return failRate, fmt.Errorf("Invalid FAIL_RATE value: %f. Must be a float between 0 and 1 inclusive.", failRate)
    	}
    
    	return failRate, err
    }
    
    func main() {
    	config, err := configFromEnv()
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	log.Printf("Starting Task #%s, Attempt #%s ...", config.taskNum, config.attemptNum)
    
    	// Simulate work
    	if config.sleepMs > 0 {
    		time.Sleep(time.Duration(config.sleepMs) * time.Millisecond)
    	}
    
    	// Simulate errors
    	if config.failRate > 0 {
    		if failure := randomFailure(config); failure != nil {
    			log.Fatalf("%v", failure)
    		}
    	}
    
    	log.Printf("Completed Task #%s, Attempt #%s", config.taskNum, config.attemptNum)
    }
    
    // Throw an error based on fail rate
    func randomFailure(config Config) error {
    	rand.Seed(time.Now().UnixNano())
    	randomFailure := rand.Float64()
    
    	if randomFailure < config.failRate {
    		return fmt.Errorf("Task #%s, Attempt #%s failed.", config.taskNum, config.attemptNum)
    	}
    	return nil
    }
    

    Os jobs do Cloud Run permitem que os usuários especifiquem o número de tarefas que o job vai executar. Esse exemplo de código mostra como usar a variável de ambiente CLOUD_RUN_TASK_INDEX integrada. Cada tarefa representa uma cópia em execução do contêiner. As tarefas geralmente são executadas em paralelo. É útil usar várias tarefas se cada uma delas puder processar independentemente um subconjunto dos dados.

    Cada tarefa está ciente do índice armazenado na variável de ambiente CLOUD_RUN_TASK_INDEX. A variável de ambiente CLOUD_RUN_TASK_COUNT integrada contém o número de tarefas fornecidas no tempo de execução do job por meio do parâmetro --tasks.

    O código mostrado também mostra como repetir tarefas, usando o método integradoCLOUD_RUN_TASK_ATTEMPT que contém o número de vezes que essa tarefa foi repetida, começando em 0 para a primeira tentativa e aumentando em 1 a cada nova tentativa, até--max-retries de dados.

    O código também permite gerar falhas como uma maneira de testar novas tentativas e gerar registros de erro para que você possa ver como eles são.

  3. Crie um arquivo go.mod com o seguinte conteúdo:

    module github.com/GoogleCloudPlatform/golang-samples/run/jobs
    
    go 1.21
    

Seu código está completo e pronto para ser empacotado em um contêiner.

Crie um contêiner de jobs, envie-o para o Artifact Registry e implante no Cloud Run

Importante: este guia de início rápido pressupõe que você tenha papéis de proprietário ou editor no projeto que está usando para este guia. Caso contrário, consulte o papel de desenvolvedor de origem do Cloud Run para ter acesso às permissões necessárias para implantar um recurso do Cloud Run a partir da origem.

Neste guia de início rápido, usamos a implantação a partir da origem, que cria o contêiner, faz upload dele para o Artifact Registry e implanta o job no Cloud Run:

gcloud run jobs deploy job-quickstart \
    --source . \
    --tasks 50 \
    --set-env-vars SLEEP_MS=10000 \
    --set-env-vars FAIL_RATE=0.1 \
    --max-retries 5 \
    --region REGION \
    --project=PROJECT_ID

em que PROJECT_ID é o ID do projeto e REGION é a região, por exemplo, us-central1. É possível mudar os vários parâmetros para os valores que você quer usar para fins de teste. O SLEEP_MS simula o trabalho, e FAIL_RATE faz com que X% das tarefas falhem. Assim, você pode testar o paralelismo e tentar novamente tarefas com falha.

Executar um job no Cloud Run

Para executar o job que você acabou de criar:

gcloud run jobs execute job-quickstart --region REGION

Substitua REGION pela região que você usou ao criar e implantar o job, por exemplo, us-central1.

A seguir

Para mais informações sobre como criar um contêiner a partir do código-fonte e enviá-lo para um repositório, consulte: