Tutorial su Cloud Pub/Sub

Questo semplice tutorial mostra la scrittura, il deployment e l'attivazione di una funzione Cloud basata su eventi con un trigger di Cloud Pub/Sub.

Se non hai mai utilizzato Pub/Sub e vuoi saperne di più, consulta la documentazione di Pub/Sub, in particolare la gestione degli argomenti e delle sottoscrizioni. Consulta Google Cloud Pub/Sub Trigger per una panoramica sull'utilizzo di sottoscrizioni e argomenti di Pub/Sub in Cloud Functions.

Se stai cercando esempi di codice per utilizzare Pub/Sub, visita il browser di esempio di Google Cloud.

Obiettivi

Costi

Questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:

  • Cloud Functions
  • Pub/Sub

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono beneficiare di una prova gratuita.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore dei progetti in Google Cloud Console, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

  4. Abilita le API Cloud Functions and Cloud Pub/Sub.

    Abilita le API

  5. Installa e inizializza l'interfaccia a riga di comando di Google Cloud.
  6. Nella pagina del selettore dei progetti in Google Cloud Console, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  7. Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.

  8. Abilita le API Cloud Functions and Cloud Pub/Sub.

    Abilita le API

  9. Installa e inizializza l'interfaccia a riga di comando di Google Cloud.
  10. Se hai già installato l'interfaccia a riga di comando gcloud, aggiornala eseguendo il comando seguente:

    gcloud components update
  11. Prepara l'ambiente di sviluppo.

Preparazione dell'applicazione

  1. Clonare il repository dell'app di esempio sul computer locale:

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    C#

    git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    Ruby

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

    PHP

    git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git

    In alternativa, puoi scaricare l'esempio come file ZIP ed estrarlo.

  2. Passa alla directory che contiene il codice di esempio di Cloud Functions per accedere a Pub/Sub:

    Node.js

    cd nodejs-docs-samples/functions/helloworld/

    Python

    cd python-docs-samples/functions/helloworld/

    Go

    cd golang-samples/functions/helloworld/

    Java

    cd java-docs-samples/functions/helloworld/hello-pubsub/

    C#

    cd dotnet-docs-samples/functions/helloworld/HelloPubSub/

    Ruby

    cd ruby-docs-samples/functions/helloworld/pubsub/

    PHP

    cd php-docs-samples/functions/helloworld_pubsub/

  3. Dai un'occhiata al codice di esempio:

    Node.js

    /**
     * Background Cloud Function to be triggered by Pub/Sub.
     * This function is exported by index.js, and executed when
     * the trigger topic receives a message.
     *
     * @param {object} message The Pub/Sub message.
     * @param {object} context The event metadata.
     */
    exports.helloPubSub = (message, context) => {
      const name = message.data
        ? Buffer.from(message.data, 'base64').toString()
        : 'World';
    
      console.log(`Hello, ${name}!`);
    };

    Python

    def hello_pubsub(event, context):
        """Background Cloud Function to be triggered by Pub/Sub.
        Args:
             event (dict):  The dictionary with data specific to this type of
                            event. The `@type` field maps to
                             `type.googleapis.com/google.pubsub.v1.PubsubMessage`.
                            The `data` field maps to the PubsubMessage data
                            in a base64-encoded string. The `attributes` field maps
                            to the PubsubMessage attributes if any is present.
             context (google.cloud.functions.Context): Metadata of triggering event
                            including `event_id` which maps to the PubsubMessage
                            messageId, `timestamp` which maps to the PubsubMessage
                            publishTime, `event_type` which maps to
                            `google.pubsub.topic.publish`, and `resource` which is
                            a dictionary that describes the service API endpoint
                            pubsub.googleapis.com, the triggering topic's name, and
                            the triggering event type
                            `type.googleapis.com/google.pubsub.v1.PubsubMessage`.
        Returns:
            None. The output is written to Cloud Logging.
        """
        import base64
    
        print("""This Function was triggered by messageId {} published at {} to {}
        """.format(context.event_id, context.timestamp, context.resource["name"]))
    
        if 'data' in event:
            name = base64.b64decode(event['data']).decode('utf-8')
        else:
            name = 'World'
        print('Hello {}!'.format(name))

    Go

    
    // Package helloworld provides a set of Cloud Functions samples.
    package helloworld
    
    import (
    	"context"
    	"log"
    )
    
    // PubSubMessage is the payload of a Pub/Sub event.
    // See the documentation for more details:
    // https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessage
    type PubSubMessage struct {
    	Data []byte `json:"data"`
    }
    
    // HelloPubSub consumes a Pub/Sub message.
    func HelloPubSub(ctx context.Context, m PubSubMessage) error {
    	name := string(m.Data) // Automatically decoded from base64.
    	if name == "" {
    		name = "World"
    	}
    	log.Printf("Hello, %s!", name)
    	return nil
    }
    

    Java

    
    import com.google.cloud.functions.BackgroundFunction;
    import com.google.cloud.functions.Context;
    import com.google.events.cloud.pubsub.v1.Message;
    import java.nio.charset.StandardCharsets;
    import java.util.Base64;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class HelloPubSub implements BackgroundFunction<Message> {
      private static final Logger logger = Logger.getLogger(HelloPubSub.class.getName());
    
      @Override
      public void accept(Message message, Context context) {
        String name = "world";
        if (message != null && message.getData() != null) {
          name = new String(
              Base64.getDecoder().decode(message.getData().getBytes(StandardCharsets.UTF_8)),
              StandardCharsets.UTF_8);
        }
        logger.info(String.format("Hello %s!", name));
        return;
      }
    }

    C#

    using CloudNative.CloudEvents;
    using Google.Cloud.Functions.Framework;
    using Google.Events.Protobuf.Cloud.PubSub.V1;
    using Microsoft.Extensions.Logging;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace HelloPubSub
    {
        public class Function : ICloudEventFunction<MessagePublishedData>
        {
            private readonly ILogger _logger;
    
            public Function(ILogger<Function> logger) =>
                _logger = logger;
    
            public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
            {
                string nameFromMessage = data.Message?.TextData;
                string name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
                _logger.LogInformation("Hello {name}", name);
                return Task.CompletedTask;
            }
        }
    }

    Ruby

    require "functions_framework"
    require "base64"
    
    FunctionsFramework.cloud_event "hello_pubsub" do |event|
      # The event parameter is a CloudEvents::Event::V1 object.
      # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
      name = Base64.decode64 event.data["message"]["data"] rescue "World"
    
      # A cloud_event function does not return a response, but you can log messages
      # or cause side effects such as sending additional events.
      logger.info "Hello, #{name}!"
    end

    PHP

    
    use CloudEvents\V1\CloudEventInterface;
    use Google\CloudFunctions\FunctionsFramework;
    
    // Register the function with Functions Framework.
    // This enables omitting the `FUNCTIONS_SIGNATURE_TYPE=cloudevent` environment
    // variable when deploying. The `FUNCTION_TARGET` environment variable should
    // match the first parameter.
    FunctionsFramework::cloudEvent('helloworldPubsub', 'helloworldPubsub');
    
    function helloworldPubsub(CloudEventInterface $event): void
    {
        $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');
    
        $cloudEventData = $event->getData();
        $pubSubData = base64_decode($cloudEventData['message']['data']);
    
        $name = $pubSubData ? htmlspecialchars($pubSubData) : 'World';
        fwrite($log, "Hello, $name!" . PHP_EOL);
    }

Deployment della funzione

Per eseguire il deployment della funzione con un trigger Pub/Sub, esegui il seguente comando nella directory che contiene il codice di esempio (o, nel caso di Java, il file pom.xml):

Node.js

gcloud functions deploy helloPubSub \
--runtime nodejs16 \
--trigger-topic YOUR_TOPIC_NAME
Puoi utilizzare i seguenti valori per il flag --runtime per specificare la versione Node.js preferita:
  • nodejs16 (consigliato)
  • nodejs14
  • nodejs12
  • nodejs10

Python

gcloud functions deploy hello_pubsub \
--runtime python39 \
--trigger-topic YOUR_TOPIC_NAME
Puoi utilizzare i seguenti valori per il flag --runtime per specificare la versione Python preferita:
  • python39 (consigliato)
  • python38
  • python37

Go

gcloud functions deploy HelloPubSub \
--runtime go116 \
--trigger-topic YOUR_TOPIC_NAME
Puoi utilizzare i seguenti valori per il flag --runtime per specificare la versione Go preferita:
  • go116 (consigliato)
  • go113
  • go111

Java

gcloud functions deploy java-pubsub-function \
--entry-point functions.HelloPubSub \
--runtime java11 \
--memory 512MB \
--trigger-topic YOUR_TOPIC_NAME
Puoi utilizzare i seguenti valori per il flag --runtime per specificare la tua versione di Java preferita:
  • java17 (anteprima)
  • java11 (consigliato)

C#

gcloud functions deploy csharp-pubsub-function \
--entry-point HelloPubSub.Function \
--runtime dotnet3 \
--trigger-topic YOUR_TOPIC_NAME

Ruby

gcloud functions deploy hello_pubsub --runtime ruby27 \
--trigger-topic YOUR_TOPIC_NAME
Puoi utilizzare i seguenti valori per il flag --runtime per specificare la versione Ruby preferita:
  • ruby30 (anteprima)
  • ruby27 (consigliato)
  • ruby26

PHP

gcloud functions deploy helloworldPubsub --runtime php74 \
--trigger-topic YOUR_TOPIC_NAME

dove YOUR_TOPIC_NAME è il nome dell'argomento Pub/Sub a cui verrà sottoscrizione la funzione.

Se YOUR_TOPIC_NAME non esiste già, questo comando lo crea automaticamente. Puoi anche creare un argomento prima di eseguire il comando deploy utilizzando Cloud Console o il seguente comando gcloud:

gcloud pubsub topics create YOUR_TOPIC_NAME

Attivazione della funzione

  1. Pubblica un messaggio nell'argomento Pub/Sub. In questo esempio, il messaggio è un nome che la funzione includerà in un saluto:

    gcloud pubsub topics publish YOUR_TOPIC_NAME --message YOUR_NAME

    Sostituisci YOUR_TOPIC_NAME con il nome dell'argomento Pub/Sub e YOUR_NAME con una stringa arbitraria.

  2. Controlla i log per assicurarti che le esecuzioni siano state completate:

    gcloud functions logs read --limit 50
    

Puoi anche pubblicare un messaggio in un argomento Pub/Sub all'interno di una funzione.

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto che hai creato per il tutorial.

Per eliminare il progetto:

  1. In Cloud Console, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto da eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Eliminazione della funzione Cloud

L'eliminazione di Cloud Functions non rimuove le risorse archiviate in Cloud Storage.

Per eliminare la Funzione Cloud creata in questo tutorial, esegui il comando seguente:

Node.js

gcloud functions delete helloPubSub 

Python

gcloud functions delete hello_pubsub 

Go

gcloud functions delete HelloPubSub 

Java

gcloud functions delete java-pubsub-function 

C#

gcloud functions delete csharp-pubsub-function 

Ruby

gcloud functions delete hello_pubsub 

PHP

gcloud functions delete helloworldPubsub 

Puoi anche eliminare Cloud Functions da Google Cloud Console.