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
Versioni delle librerie client consigliate
- Per prestazioni ottimali, utilizza la versione più recente della libreria client, Python v2.13.6 o versioni successive, Java v1.139.0 o versioni successive, PHP v1.39.0 o versioni successive, C# v3.2.0 o versioni successive, C++ v2.1.0, Go v1.25.1 o versioni successive, Node v3.2.0 o versioni successive e Ruby v2.12.1 o versioni successive.
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 anchemaxInboundMetadataSizesu almeno 1 MB durante la creazione diTransportChannelProvider. Per questa configurazione, puoi utilizzare ilInstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()o ilManagedChannelBuilder.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":
Nella Google Cloud console, vai alla pagina Sottoscrizioni.
Fai clic su Crea sottoscrizione.
Inserisci l'ID sottoscrizione.
Scegli o crea un argomento dal menu a discesa.
La sottoscrizione riceve i messaggi dall'argomento.
Nella sezione Consegna "exactly-once", seleziona Abilita la consegna "exactly-once".
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++ .
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# .
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.
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.
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.
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.
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.
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.
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.
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_countLa 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 richiesteModifyAckDeadlineche per le richiesteacknowledgment.service.serviceruntime.googleapis.com/api/request_countLa metrica può essere utilizzata per acquisire gli errori delle richiesteModifyAckDeadlineoacknowledgmentnei 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_counte le librerie client supportate li riprovano automaticamente. Tuttavia, non è possibile riprovare gli errori relativi a ID di conferma di ricezione non validi.