Ordinamento dei messaggi

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

In questa pagina viene spiegato come ricevere i messaggi in ordine.

Per ulteriori informazioni sulla ricezione dei messaggi, consulta la panoramica degli iscritti.

Ricezione dei messaggi in ordine

Se i messaggi hanno la stessa chiave di ordinamento e si trovano nella stessa area geografica, puoi abilitare l'ordinamento dei messaggi e ricevere i messaggi nell'ordine in cui li riceve il servizio Pub/Sub.

Pub/Sub recapita ciascun messaggio almeno una volta, quindi il servizio Pub/Sub potrebbe recapitare di nuovo i messaggi. Quando ricevi messaggi in ordine e il servizio Pub/Sub riconsegna un messaggio con una chiave di ordinamento, Pub/Sub mantiene l'ordine anche ripubblicando i messaggi successivi con la stessa chiave di ordinamento. Il servizio Pub/Sub reindirizza questi messaggi nell'ordine in cui li ha ricevuti in origine.

Quando il servizio Pub/Sub reindirizza un messaggio con una chiave di ordinamento, il servizio Pub/Sub reindirizza anche tutti i messaggi successivi con la stessa chiave di ordinamento, inclusi i messaggi confermati. Se sia l'ordinamento dei messaggi sia un argomento messaggi non recapitabili siano abilitati per una sottoscrizione, ciò potrebbe non essere vero, poiché Pub/Sub inoltra i messaggi agli argomenti non recapitabili in base al meglio. Una volta ricevuti i messaggi ricaricati, devi confermarli di nuovo. Non è garantito che i messaggi successivi vengano inviati senza che quelli precedenti vengano confermati.

Chiavi ordinate e consegna messaggi

I messaggi con la stessa chiave di ordinamento sono garantiti per la consegna nell'ordine.

Non è garantito che i messaggi con chiavi di ordinamento diversi vengano recapitati indipendentemente dall'ora di pubblicazione.

L'impossibilità di riconoscere un messaggio potrebbe rallentare la consegna dei messaggi per altre chiavi di ordinamento. Questo problema può verificarsi quando i server si riavviano in modo imprevisto o vengono apportate modifiche all'insieme di server utilizzati a causa di modifiche al traffico. Per mantenere l'ordine in tali eventi, tutti i messaggi pubblicati nel vecchio server devono essere confermati prima della consegna dei messaggi provenienti dal nuovo server, anche se riguardano chiavi di ordinamento diverse. Se non puoi garantire il riconoscimento tempestivo di tutti i messaggi, valuta la possibilità di allegare un argomento messaggi non recapitabili alla sottoscrizione. L'ordine dei messaggi potrebbe non essere mantenuto quando vengono scritti nell'argomento messaggi non recapitabili.

Attivazione dell'ordinamento dei messaggi

Per ricevere i messaggi in ordine, imposta la proprietà di ordinamento dei messaggi nella sottoscrizione da cui ricevi i messaggi. La ricezione dei messaggi in ordine potrebbe aumentare la latenza.

Puoi impostare la proprietà dell'ordinamento dei messaggi quando crei una sottoscrizione utilizzando la console Google Cloud, Google Cloud CLI o l'API Pub/Sub.

Console

Per creare una sottoscrizione con la proprietà dell'ordinamento dei messaggi, procedi nel seguente modo:

  1. Nella console Google Cloud, vai alla pagina Abbonamenti.

    Vai alla pagina Abbonamenti

  2. Fai clic su Crea sottoscrizione.

  3. Inserisci un ID abbonamento.

  4. Scegli un argomento da cui ricevere messaggi.

  5. Nella sezione Ordine dei messaggi, seleziona Ordina i messaggi con una chiave di ordinamento.

  6. Fai clic su Crea.

gcloud

Per creare una sottoscrizione con la proprietà di ordinamento dei messaggi, utilizza il comando gcloud pubsub subscriptions create e il flag --enable-message-ordering:

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --enable-message-ordering

Sostituisci SUBSCRIPTION_ID con l'ID dell'abbonamento.

Se la richiesta ha esito positivo, la riga di comando mostra un messaggio di conferma:

Created subscription [SUBSCRIPTION_ID].

REST

Per creare una sottoscrizione con la proprietà di ordinamento dei messaggi, invia una richiesta PUT come la seguente:

PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Authorization: Bearer $(gcloud auth application-default print-access-token)

Sostituisci quanto segue:

  • PROJECT_ID: l'ID del progetto con l'argomento
  • SUBSCRIPTION_ID: ID dell'abbonamento

Nel corpo della richiesta, specifica quanto segue:

{
  "topic": TOPIC_ID,
  "enableMessageOrdering": true,
}

Sostituisci TOPIC_ID con l'ID dell'argomento da collegare alla sottoscrizione.

Se la richiesta ha esito positivo, la risposta è l'abbonamento in formato JSON:

{
  "name": projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID,
  "topic": projects/PROJECT_ID/topics/TOPIC_ID,
  "enableMessageOrdering": true,
}

C++

Prima di provare questo esempio, segui le istruzioni di configurazione di C++ in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C++.

namespace pubsub = ::google::cloud::pubsub;
[](pubsub::SubscriptionAdminClient client, std::string const& project_id,
   std::string const& topic_id, std::string const& subscription_id) {
  auto sub = client.CreateSubscription(
      pubsub::Topic(project_id, std::move(topic_id)),
      pubsub::Subscription(project_id, std::move(subscription_id)),
      pubsub::SubscriptionBuilder{}.enable_message_ordering(true));
  if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The subscription already exists\n";
    return;
  }
  if (!sub) throw std::move(sub).status();

  std::cout << "The subscription was successfully created: "
            << sub->DebugString() << "\n";
}

C#

Prima di provare questo esempio, segui le istruzioni di configurazione di C# in Guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C#.


using Google.Cloud.PubSub.V1;
using Grpc.Core;

public class CreateSubscriptionWithOrderingSample
{
    public Subscription CreateSubscriptionWithOrdering(string projectId, string subscriptionId, string topicId)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        var topicName = TopicName.FromProjectTopic(projectId, topicId);
        var subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);

        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            EnableMessageOrdering = true
        };

        Subscription subscription = null;
        try
        {
            subscription = subscriber.CreateSubscription(subscriptionRequest);
        }
        catch (RpcException e) when (e.Status.StatusCode == StatusCode.AlreadyExists)
        {
            // Already exists.  That's fine.
        }
        return subscription;
    }
}

Go

Prima di provare questo esempio, segui le istruzioni per la configurazione di Go in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento per l'API Pub/Sub Go.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/pubsub"
)

func createWithOrdering(w io.Writer, projectID, subID string, topic *pubsub.Topic) error {
	// projectID := "my-project-id"
	// subID := "my-sub"
	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %v", err)
	}
	defer client.Close()

	// Message ordering can only be set when creating a subscription.
	sub, err := client.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
		Topic:                 topic,
		AckDeadline:           20 * time.Second,
		EnableMessageOrdering: true,
	})
	if err != nil {
		return fmt.Errorf("CreateSubscription: %v", err)
	}
	fmt.Fprintf(w, "Created subscription: %v\n", sub)
	return nil
}

Java

Prima di provare questo esempio, segui le istruzioni di configurazione di Java in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento per l'API Java di Pub/Sub.

import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.Subscription;
import java.io.IOException;

public class CreateSubscriptionWithOrdering {
  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String topicId = "your-topic-id";
    String subscriptionId = "your-subscription-id";

    createSubscriptionWithOrderingExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithOrderingExample(
      String projectId, String topicId, String subscriptionId) throws IOException {
    try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {

      ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
      ProjectSubscriptionName subscriptionName =
          ProjectSubscriptionName.of(projectId, subscriptionId);

      Subscription subscription =
          subscriptionAdminClient.createSubscription(
              Subscription.newBuilder()
                  .setName(subscriptionName.toString())
                  .setTopic(topicName.toString())
                  // Set message ordering to true for ordered messages in the subscription.
                  .setEnableMessageOrdering(true)
                  .build());

      System.out.println("Created a subscription with ordering: " + subscription.getAllFields());
    }
  }
}

Node.js

Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento per l'API Pub/Sub Node.js.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';

// Imports the Google Cloud client library
const {PubSub} = require('@google-cloud/pubsub');

// Creates a client; cache this for further use
const pubSubClient = new PubSub();

async function createSubscriptionWithOrdering(
  topicNameOrId,
  subscriptionNameOrId
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableMessageOrdering: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with ordering enabled.`
  );

  console.log(
    'To process messages in order, remember to add an ordering key to your messages.'
  );
}

Python

Prima di provare questo esempio, segui le istruzioni di configurazione di Python in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento per l'API Python Pub/Sub.

from google.cloud import pubsub_v1

# TODO(developer): Choose an existing topic.
# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

publisher = pubsub_v1.PublisherClient()
subscriber = pubsub_v1.SubscriberClient()
topic_path = publisher.topic_path(project_id, topic_id)
subscription_path = subscriber.subscription_path(project_id, subscription_id)

with subscriber:
    subscription = subscriber.create_subscription(
        request={
            "name": subscription_path,
            "topic": topic_path,
            "enable_message_ordering": True,
        }
    )
    print(f"Created subscription with ordering: {subscription}")

Ruby

Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby in Guida rapida: utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento per l'API Pub/Sub Ruby.

# topic_id        = "your-topic-id"
# subscription_id = "your-subscription-id"
require "google/cloud/pubsub"

pubsub = Google::Cloud::Pubsub.new

topic        = pubsub.topic topic_id
subscription = topic.subscribe subscription_id,
                               message_ordering: true

puts "Pull subscription #{subscription_id} created with message ordering."

Dopo aver impostato la proprietà dell'ordinamento dei messaggi, il servizio Pub/Sub fornisce i messaggi con la stessa chiave di ordinamento nell'ordine in cui il servizio Pub/Sub riceve i messaggi. Ad esempio, se un editore invia due messaggi con la stessa chiave di ordinamento, il servizio Pub/Sub recapita prima il messaggio meno recente.

Passaggi successivi