Consegna "exactly-once"

Questa pagina spiega come ricevere e confermare i messaggi utilizzando la funzionalità "exactly-once" di Pub/Sub, che consente di monitorare ed evitare l'elaborazione duplicata dei messaggi. Quando la funzionalità è abilitata, Pub/Sub fornisce la seguente semantica:

  • I sottoscrittori possono determinare se le conferme di ricezione dei messaggi sono andate a buon fine.

  • Non si verifica alcuna riconsegna dopo che il messaggio è stato confermato correttamente.

  • Non si verifica alcuna riconsegna mentre un messaggio è in sospeso. Un messaggio è considerato in sospeso fino alla scadenza della conferma di ricezione o fino a quando non viene confermato.

  • In caso di più consegne valide, a causa della scadenza della conferma di ricezione o della conferma di ricezione negativa avviata dal client, è possibile utilizzare solo l'ID di conferma di ricezione più recente per confermare il messaggio. Tutte le richieste con un ID di conferma di ricezione precedente non vanno a buon fine.

Con la funzionalità "exactly-once" abilitata, i sottoscrittori possono assicurarsi che i messaggi vengano elaborati una sola volta seguendo queste linee guida:

  • Conferma i messaggi entro la scadenza della conferma di ricezione.

  • Mantieni le informazioni sullo stato di avanzamento dell'elaborazione di un messaggio finché non viene confermato correttamente.

  • Utilizza le informazioni sullo stato di avanzamento dell'elaborazione di un messaggio per evitare il lavoro duplicato quando una conferma di ricezione non va a buon fine.

Solo il tipo di sottoscrizione pull supporta la consegna "exactly-once", inclusi i sottoscrittori che utilizzano l' API StreamingPull. Le sottoscrizioni push e di esportazione non supportano la consegna "exactly-once".

Pub/Sub supporta la consegna "exactly-once", all'interno di una regione cloud, in base a un ID messaggio univoco definito da Pub/Sub

Riconsegna e duplicato

È importante comprendere la differenza tra le riconsegne previste e quelle impreviste.

  • Una riconsegna può avvenire a causa della conferma di ricezione negativa di un messaggio avviata dal client o quando il client non estende la scadenza della conferma di ricezione del messaggio prima della scadenza della conferma di ricezione. Le riconsegne sono considerate valide e il sistema funziona come previsto.

    Per risolvere i problemi relativi alle riconsegne, consulta Gestire i duplicati.

  • Un duplicato si verifica quando un messaggio viene inviato di nuovo dopo una conferma di ricezione riuscita o prima della scadenza della conferma di ricezione.

  • Un messaggio riconsegnato conserva lo stesso ID messaggio tra i tentativi di riconsegna.

Le sottoscrizioni con la consegna "exactly-once" abilitata non ricevono consegne duplicate.

Supporto della consegna "exactly-once" nelle librerie client

  • Le librerie client supportate hanno un'interfaccia per la conferma di ricezione con risposta (ad esempio, Go). Puoi utilizzare questa interfaccia per verificare se la richiesta di conferma di ricezione è andata a buon fine. Se la richiesta di conferma di ricezione va a buon fine, i client non riceveranno una riconsegna. Se la richiesta di conferma di ricezione non va a buon fine, i client possono prevedere una riconsegna.

  • I client possono anche utilizzare le librerie client supportate senza l'interfaccia di conferma di ricezione. Tuttavia, in questi casi, gli errori di conferma di ricezione possono comportare riconsegne silenziose dei messaggi.

  • Le librerie client supportate hanno interfacce per impostare il tempo minimo di estensione del lease (ad esempio: Go). Devi impostare un valore elevato per l'estensione minima del lease per evitare la scadenza della conferma di ricezione correlata alla rete. Il valore massimo è impostato su 600 secondi.

  • Se utilizzi la libreria client Java e inizializzi il sottoscrittore con un canale gRPC personalizzato utilizzando il setChannelProvider() metodo, ti consigliamo di impostare anche maxInboundMetadataSize su almeno 1 MB durante la creazione di TransportChannelProvider. Per questa configurazione, puoi utilizzare il InstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize() o il ManagedChannelBuilder.maxInboundMetadataSize() metodo.

I valori e l'intervallo predefiniti per le variabili correlate alla consegna "exactly-once" e i nomi delle variabili potrebbero variare a seconda delle librerie client. Ad esempio, nella libreria client Java, le seguenti variabili controllano la consegna "exactly-once".

Variabile Descrizione Valore
setEnableExactlyOnceDelivery Attiva o disattiva la consegna "exactly-once". true o false Valore predefinito=false
minDurationPerAckExtension Il tempo minimo in secondi da utilizzare per estendere la scadenza della conferma di ricezione della modifica. Intervallo=da 0 a 600 Valore predefinito=nessuno
maxDurationPerAckExtension Il tempo massimo in secondi da utilizzare per estendere la scadenza della conferma di ricezione della modifica. Intervallo=da 0 a 600 Valore predefinito=nessuno

Nel caso della consegna "exactly-once", la modifyAckDeadline o acknowledgment richiesta a Pub/Sub non va a buon fine quando l'ID di conferma di ricezione è già scaduto. In questi casi, il servizio considera l'ID di conferma di ricezione scaduto non valido, poiché una consegna più recente potrebbe essere già in corso. Questo è il comportamento previsto per la consegna "exactly-once". Vengono visualizzate le richieste acknowledgment e ModifyAckDeadline che restituiscono una risposta INVALID_ARGUMENT. Quando la consegna "exactly-once" è disattivata, queste richieste restituiscono OK in caso di ID di conferma di ricezione scaduti.

Per assicurarti che le richieste acknowledgment e ModifyAckDeadline abbiano ID di conferma di ricezione validi, valuta la possibilità di impostare un valore elevato per minDurationPerAckExtension.

Considerazioni regionali

La garanzia di consegna "exactly-once" si applica solo quando i sottoscrittori si connettono al servizio nella stessa regione. Se l'applicazione di sottoscrizione è distribuita su più regioni, può comportare la consegna di messaggi duplicati, anche quando la consegna "exactly-once" è abilitata. I publisher possono inviare messaggi a qualsiasi regione e la garanzia "exactly-once" viene comunque mantenuta.

Quando esegui l'applicazione all'interno di Google Cloud, per impostazione predefinita si connette all'endpoint Pub/Sub nella stessa regione. Pertanto, l'esecuzione dell'applicazione in una singola regione all'interno di Google Cloud in genere garantisce l'interazione con una singola regione.

Quando esegui l'applicazione di sottoscrizione al di fuori di Google Cloud o in più regioni, puoi garantire la connessione a una singola regione utilizzando un endpoint di località durante la configurazione del client Pub/Sub. Tutti gli endpoint di località per Pub/Sub puntano a singole regioni. Per saperne di più sugli endpoint di località, consulta Endpoint Pub/Sub. Per un elenco di tutti gli endpoint di località per Pub/Sub, consulta Elenco degli endpoint di località.

Creare sottoscrizioni con consegna "exactly-once"

Puoi creare una sottoscrizione con consegna "exactly-once" utilizzando la Google Cloud console, Google Cloud CLI, la libreria client o l'API Pub/Sub.

Sottoscrizione pull

Console

Per creare una sottoscrizione pull con consegna "exactly-once":

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

    Vai ad Abbonamenti

  2. Fai clic su Crea sottoscrizione.

  3. Inserisci l'ID sottoscrizione.

  4. Scegli o crea un argomento dal menu a discesa.

    La sottoscrizione riceve i messaggi dall'argomento.

  5. Nella sezione Consegna "exactly-once", seleziona Abilita la consegna "exactly-once".

  6. Fai clic su Crea.

gcloud

Per creare una sottoscrizione pull con consegna "exactly-once", utilizza il gcloud pubsub subscriptions create comando con il --enable-exactly-once-delivery flag:

gcloud pubsub subscriptions create SUBSCRIPTION_ID \
  --topic=TOPIC_ID \
  --enable-exactly-once-delivery

Sostituisci quanto segue:

  • SUBSCRIPTION_ID: l'ID della sottoscrizione da creare
  • TOPIC_ID: l'ID dell'argomento da collegare alla sottoscrizione

REST

Per creare una sottoscrizione con consegna "exactly-once", utilizza il projects.subscriptions.create metodo.

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

Sostituisci quanto segue:

  • PROJECT_ID: l'ID progetto del progetto in cui creare la sottoscrizione
  • SUBSCRIPTION_ID: l'ID della sottoscrizione da creare

Per creare una sottoscrizione pull con consegna "exactly-once", specifica quanto segue nel corpo della richiesta:

{
  "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
  "enableExactlyOnceDelivery": true,
}

Sostituisci quanto segue:

  • PROJECT_ID: l'ID progetto del progetto con l'argomento
  • TOPIC_ID: l'ID dell'argomento da collegare alla sottoscrizione

C++

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

namespace pubsub = ::google::cloud::pubsub;
namespace pubsub_admin = ::google::cloud::pubsub_admin;
[](pubsub_admin::SubscriptionAdminClient client,
   std::string const& project_id, std::string const& topic_id,
   std::string const& subscription_id) {
  google::pubsub::v1::Subscription request;
  request.set_name(
      pubsub::Subscription(project_id, subscription_id).FullName());
  request.set_topic(pubsub::Topic(project_id, topic_id).FullName());
  request.set_enable_exactly_once_delivery(true);
  auto sub = client.CreateSubscription(request);
  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 saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub C# .


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

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

        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            EnableExactlyOnceDelivery = 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;
    }
}

Vai

L'esempio seguente utilizza la versione principale della libreria client Go Pub/Sub (v2). Se utilizzi ancora la libreria v1, consulta la guida alla migrazione alla v2. Per visualizzare un elenco di esempi di codice della versione 1, consulta gli esempi di codice deprecati.

Prima di provare questo esempio, segui le istruzioni di configurazione di Go in Guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Go.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub/v2"
	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
)

func createSubscriptionWithExactlyOnceDelivery(w io.Writer, projectID, topic, subscription string) error {
	// projectID := "my-project-id"
	// topic := "projects/my-project-id/topics/my-topic"
	// subscription := "projects/my-project/subscriptions/my-sub"
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	pbSub := &pubsubpb.Subscription{
		Name:                      subscription,
		Topic:                     topic,
		EnableExactlyOnceDelivery: true,
	}
	sub, err := client.SubscriptionAdminClient.CreateSubscription(ctx, pbSub)
	if err != nil {
		return fmt.Errorf("failed to create exactly once sub: %w", err)
	}
	fmt.Fprintf(w, "Created a subscription with exactly once delivery enabled: %v\n", sub)
	return nil
}

Java

Prima di provare questo esempio, segui le istruzioni di configurazione di Java in Guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Java.

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 CreateSubscriptionWithExactlyOnceDelivery {
  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";

    createSubscriptionWithExactlyOnceDeliveryExample(projectId, topicId, subscriptionId);
  }

  public static void createSubscriptionWithExactlyOnceDeliveryExample(
      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())
                  // Enable exactly once delivery in the subscription.
                  .setEnableExactlyOnceDelivery(true)
                  .build());

      System.out.println(
          "Created a subscription with exactly once delivery enabled: "
              + subscription.getAllFields());
    }
  }
}

Python

Prima di provare questo esempio, segui le istruzioni di configurazione di Python in Guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Python.

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_exactly_once_delivery": True,
        }
    )
    print(
        f"Created subscription with exactly once delivery enabled: {subscription}"
    )

Node.js

Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js in guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'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 createSubscriptionWithExactlyOnceDelivery(
  topicNameOrId,
  subscriptionNameOrId,
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableExactlyOnceDelivery: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with exactly-once delivery.`,
  );
  console.log(
    'To process messages, remember to check the return value of ackWithResponse().',
  );
}

Node.js

Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js in guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'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
import {PubSub} from '@google-cloud/pubsub';

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

async function createSubscriptionWithExactlyOnceDelivery(
  topicNameOrId: string,
  subscriptionNameOrId: string,
) {
  // Creates a new subscription
  await pubSubClient
    .topic(topicNameOrId)
    .createSubscription(subscriptionNameOrId, {
      enableExactlyOnceDelivery: true,
    });
  console.log(
    `Created subscription ${subscriptionNameOrId} with exactly-once delivery.`,
  );
  console.log(
    'To process messages, remember to check the return value of ackWithResponse().',
  );
}

Ruby

L'esempio seguente utilizza la libreria client Ruby Pub/Sub v3. Se utilizzi ancora la libreria v2, consulta la guida alla migrazione alla v3. Per visualizzare un elenco di esempi di codice Ruby v2, consulta gli esempi di codice deprecati.

Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby in Guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Ruby.

# project_id = "your-project-id"
# topic_id = "your-topic-id"
# subscription_id = "your-subscription-id"

pubsub = Google::Cloud::PubSub.new project_id: project_id
subscription_admin = pubsub.subscription_admin

subscription = subscription_admin.create_subscription \
  name: pubsub.subscription_path(subscription_id),
  topic: pubsub.topic_path(topic_id),
  enable_exactly_once_delivery: true

puts "Created subscription with exactly once delivery enabled: " \
     "#{subscription_id}"

PHP

Prima di provare questo esempio, segui le istruzioni di configurazione di PHP in guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub PHP.

use Google\Cloud\PubSub\PubSubClient;

/**
 * Creates a Pub/Sub subscription with `Exactly Once Delivery` enabled.
 *
 * @param string $projectId  The Google project ID.
 * @param string $topicName  The Pub/Sub topic name.
 * @param string $subscriptionName  The Pub/Sub subscription name.
 */
function create_subscription_with_exactly_once_delivery(
    string $projectId,
    string $topicName,
    string $subscriptionName
): void {
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $subscription = $topic->subscription($subscriptionName);
    $subscription->create([
        'enableExactlyOnceDelivery' => true
    ]);

    // Exactly Once Delivery status for the subscription
    $status = $subscription->info()['enableExactlyOnceDelivery'];

    printf('Subscription created with exactly once delivery status: %s' . PHP_EOL, $status ? 'true' : 'false');
}

Monitorare le sottoscrizioni con consegna "exactly-once"

La subscription/exactly_once_warning_count metrica registra il numero di eventi che possono portare a possibili riconsegne (valide o duplicate). Questa metrica conteggia le volte in cui Pub/Sub non riesce a elaborare le richieste associate agli ID di conferma di ricezione (richiesta ModifyAckDeadline o acknowledgment). I motivi dell'errore potrebbero essere basati sul server o sul client. Ad esempio, se il livello di persistenza utilizzato per mantenere le informazioni sulla consegna "exactly-once" non è disponibile, si tratta di un evento basato sul server. Se il client tenta di confermare un messaggio con un ID di conferma di ricezione non valido, si tratta di un evento basato sul client.

Informazioni sulla metrica

subscription/exactly_once_warning_count acquisisce gli eventi che potrebbero o meno portare a riconsegne effettive e può essere rumorosa in base al comportamento del client. Ad esempio, le richieste ripetute acknowledgment o ModifyAckDeadline con ID di conferma di ricezione non validi aumentano ripetutamente la metrica.

Le seguenti metriche sono utili anche per comprendere il comportamento del client:

  • subscription/expired_ack_deadlines_count La metrica mostra il numero di scadenze degli ID di conferma di ricezione. Le scadenze degli ID di conferma di ricezione possono causare errori sia per le richieste ModifyAckDeadline che per le richieste acknowledgment.

  • service.serviceruntime.googleapis.com/api/request_count La metrica può essere utilizzata per acquisire gli errori delle richieste ModifyAckDeadline o acknowledgment nei casi in cui le richieste raggiungono Google Cloud Pub/Sub, ma non lo raggiungono. Esistono errori che questa metrica non acquisisce, ad esempio quando i client sono disconnessi da Google Cloud.

Nella maggior parte dei casi di eventi di errore che possono essere riprovati, le librerie client supportate riprovano automaticamente la richiesta.

Quote

Le sottoscrizioni con consegna "exactly-once" sono soggette a requisiti di quota aggiuntivi. Queste quote vengono applicate a:

  • Numero di messaggi utilizzati dalle sottoscrizioni con consegna "exactly-once" abilitata per regione.
  • Numero di messaggi confermati o la cui scadenza è stata estesa quando si utilizzano sottoscrizioni con consegna "exactly-once" abilitata per regione.

Per saperne di più su queste quote, consulta la tabella nell'argomento Quote.

Consegna "exactly-once" e sottoscrizioni ordinate

Pub/Sub supporta la consegna "exactly-once" con la consegna ordinata.

Quando utilizzi l'ordinamento con la consegna "exactly-once", Pub/Sub si aspetta che le conferme di ricezione siano in ordine. Se le conferme di ricezione non sono in ordine, il servizio non riesce a soddisfare le richieste con errori temporanei. Se la scadenza della conferma di ricezione scade prima di una conferma di ricezione in ordine per la consegna, il client riceverà una riconsegna del messaggio. Per questo motivo, quando utilizzi l'ordinamento con la consegna "exactly-once", la velocità effettiva del client è limitata a un ordine di migliaia di messaggi al secondo.

Consegna "exactly-once" e sottoscrizioni push

Pub/Sub supporta la consegna "exactly-once" solo con le sottoscrizioni pull.

I client che utilizzano i messaggi dalle sottoscrizioni push confermano i messaggi rispondendo alle richieste push con una risposta riuscita. Tuttavia, i client non sanno se la sottoscrizione Pub/Sub ha ricevuto la risposta e l'ha elaborata. Questo è diverso dalle sottoscrizioni pull, in cui le richieste di conferma di ricezione vengono avviate dai client e la sottoscrizione Pub/Sub risponde se la richiesta è stata elaborata correttamente. Per questo motivo, la semantica della consegna "exactly-once" non si allinea bene con le sottoscrizioni push.

Cose da sapere

  • Se la scadenza della conferma di ricezione non viene specificata al momento di CreateSubscription, le sottoscrizioni con consegna "exactly-once" abilitata avranno una scadenza predefinita di 60 secondi.

  • Le scadenze predefinite più lunghe per la conferma di ricezione sono utili per evitare la riconsegna causata da eventi di rete. Le librerie client supportate non utilizzano la scadenza predefinita per la conferma di ricezione della sottoscrizione.

  • Le sottoscrizioni con consegna "exactly-once" hanno una latenza dalla pubblicazione alla sottoscrizione significativamente più elevata rispetto alle sottoscrizioni normali.

  • Se hai bisogno di throughput elevato, i client con consegna "exactly-once" devono utilizzare anche il pull di streaming.

  • Una sottoscrizione potrebbe ricevere più copie dello stesso messaggio a causa di duplicati lato pubblicazione, anche con la consegna "exactly-once" abilitata. I duplicati lato pubblicazione possono essere dovuti a più tentativi di pubblicazione univoci da parte del client di pubblicazione o del servizio Pub/Sub. Più pubblicazioni univoche da parte del client di pubblicazione, tra i tentativi, comportano riconsegne con diversi ID messaggio. Più pubblicazioni univoche da parte del servizio Pub/Sub, per rispondere a una richiesta di pubblicazione del client, comportano riconsegne con gli stessi ID messaggio.

  • Puoi riprovare gli errori in subscription/exactly_once_warning_count e le librerie client supportate li riprovano automaticamente. Tuttavia, non è possibile riprovare gli errori relativi a ID di conferma di ricezione non validi.