Crea ed esegui un job Go in Cloud Run

Scopri come creare un semplice job Cloud Run, quindi esegui il deployment dall'origine, che pacchettizza automaticamente il codice in un'immagine container, carica l'immagine container in Artifact Registry e poi esegue il deployment in Cloud Run. Puoi utilizzare altre lingue oltre a quelle mostrate.

Prima di iniziare

  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. Abilita l'API Cloud Run Admin e l'API Cloud Build:

    gcloud services enable run.googleapis.com \
        cloudbuild.googleapis.com

    Dopo aver attivato l'API Cloud Run Admin, l'account di servizio predefinito di Compute Engine viene creato automaticamente.

  11. Affinché Cloud Build possa compilare le tue origini, concedi il ruolo Account di servizio Cloud Build all'account di servizio predefinito di Compute Engine eseguendo quanto segue:

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

    Sostituisci PROJECT_NUMBER con il numero del progetto Google Cloud e PROJECT_ID con l'ID progetto Google Cloud. Per istruzioni dettagliate su come trovare l'ID progetto e il numero del progetto, consulta Creazione e gestione dei progetti.

    La propagazione del ruolo dell'account di servizio Cloud Build all'account di servizio predefinito di Compute Engine richiede un paio di minuti.

Scrittura del job di esempio

Per scrivere un job in Go:

  1. Crea una nuova directory denominata jobs e cambia directory al suo interno:

    mkdir jobs
    cd jobs
    
  2. Nella stessa directory, crea un file main.go per il codice del job effettivo. Copia le seguenti righe di esempio:

    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
    }
    

    I job Cloud Run consentono agli utenti di specificare il numero di attività da eseguire. Questo codice campione mostra come utilizzare la variabile di ambiente CLOUD_RUN_TASK_INDEX incorporata. Ogni attività rappresenta una copia in esecuzione del contenitore. Tieni presente che in genere le attività vengono eseguite in parallelo. L'utilizzo di più attività è utile se ciascuna può elaborare in modo indipendente un sottoinsieme di dati.

    Ogni attività è consapevole del proprio indice, memorizzato nella variabile di ambiente CLOUD_RUN_TASK_INDEX. La variabile di ambiente CLOUD_RUN_TASK_COUNT integrata contiene il numero di attività fornite al momento dell'esecuzione del job tramite il parametro --tasks.

    Il codice mostrato mostra anche come ripetere le attività utilizzando la variabile di ambiente CLOUD_RUN_TASK_ATTEMPT integrata, che contiene il numero di volte in cui è stata ripetuta l'attività, a partire da 0 per il primo tentativo e incrementandosi di 1 per ogni tentativo successivo, fino a --max-retries.

    Il codice ti consente anche di generare errori per testare i tentativi di nuovo caricamento e di generare log di errore per consentirti di visualizzarne la forma.

  3. Crea un file go.mod con i seguenti contenuti:

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

Il codice è completo e pronto per essere pacchettizzato in un contenitore.

Crea il contenitore dei job, invialo ad Artifact Registry ed esegui il deployment in Cloud Run

Importante:questa guida introduttiva presuppone che tu disponga dei ruoli di proprietario o editor nel progetto che stai utilizzando. In caso contrario, consulta il ruolo Sviluppatore di origini Cloud Run per le autorizzazioni necessarie per eseguire il deployment di una risorsa Cloud Run dall'origine.

Questa guida rapida utilizza il deployment da sorgente, che crea il container, lo carica in Artifact Registry ed esegue il deployment del job in 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

dove PROJECT_ID è l'ID progetto e REGION è la regione, ad esempio us-central1. Tieni presente che puoi modificare i vari parametri in base ai valori che vuoi utilizzare per i test. SLEEP_MS simula il lavoro e FAIL_RATE causa il fallimento del X% delle attività, in modo da poter sperimentare il parallelismo e riprovare le attività non riuscite.

Esegui un job in Cloud Run

Per eseguire il job appena creato:

gcloud run jobs execute job-quickstart --region REGION

Sostituisci REGION con la regione utilizzata per creare e implementare il job, ad esempio us-central1.

Passaggi successivi

Per saperne di più sulla creazione di un container dall'origine del codice e su come eseguirne il push in un repository, consulta: