Questa pagina spiega come ricevere e confermare i messaggi utilizzando la funzionalità exactly-once di Pub/Sub, che ti consente di monitorare e impedire l'elaborazione duplicata dei messaggi. Quando la funzionalità è attivata, Pub/Sub fornisce la seguente semantica:
Gli abbonati possono determinare se i messaggi di conferma sono andati a buon fine.
Non viene eseguito alcun nuovo recapito dopo la conferma del messaggio.
Non viene eseguita alcuna nuova consegna mentre un messaggio è in sospeso. Un messaggio viene considerato in sospeso fino alla scadenza della scadenza per il riconoscimento o fino a quando il messaggio non viene confermato.
In caso di più recapiti validi, a causa della scadenza del termine per il riconoscimento o del riconoscimento negativo avviato dal cliente, per il riconoscimento del messaggio può essere utilizzato solo l'ID di riconoscimento più recente. Eventuali richieste con un ID di conferma precedente non vanno a buon fine.
Con l'attivazione di exactly-once, gli abbonati possono assicurarsi che i messaggi vengano elaborati una sola volta seguendo queste linee guida:
Conferma i messaggi entro la scadenza di conferma.
Mantieni le informazioni sullo stato di avanzamento dell'elaborazione di un messaggio fino a quando non viene confermato correttamente.
Utilizza le informazioni sull'avanzamento dell'elaborazione di un messaggio per evitare di duplicare il lavoro quando un ack non va a buon fine.
Solo il tipo di sottoscrizione pull supporta l'invio esattamente una volta, inclusi gli abbonati che utilizzano l'API StreamingPull. Le sottoscrizioni push ed esportazione non supportano la consegna "exactly-once".
Pub/Sub supporta la consegna "exactly-once", all'interno di una regione cloud, basata su un ID messaggio unico definito da Pub/Sub.
Versioni consigliate delle librerie client
- Per il massimo rendimento, utilizza la versione più recente della libreria client, Python v2.13.6 o successiva, Java v1.120.11 o successiva, PHP v1.39.0 o successiva, C# v3.2.0 o successiva, C++ v2.1.0, Go v1.25.1 o successiva, Node v3.2.0 o successiva e Ruby v2.12.1 o successiva.
Ricaricamento e duplicato
È importante comprendere la differenza tra le reimportazioni previste e quelle impreviste.
Un nuovo invio può verificarsi a causa di un 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 reimportazioni sono considerate valide e il sistema funziona come previsto.
Per risolvere i problemi relativi alle importazioni ripetute, consulta Gestire i duplicati.
Un messaggio è un duplicato quando viene inviato di nuovo dopo una conferma di ricezione riuscita o prima della scadenza della conferma di ricezione.
Un messaggio ridistribuito conserva lo stesso ID messaggio tra i tentativi di nuova distribuzione.
Le sottoscrizioni con la consegna "exactly-once" abilitata non ricevono messaggi duplicati.
Supporto della consegna "exactly-once" nelle librerie client
Le librerie client supportate hanno un'interfaccia per l'acknowledgement con risposta (ad esempio Go). Puoi utilizzare questa interfaccia per verificare se la richiesta di conferma è andata a buon fine. Se la richiesta di conferma va a buon fine, i client non riceveranno nuovamente i dati. Se la richiesta di conferma non va a buon fine, i clienti possono aspettarsi una nuova consegna.
I client possono anche utilizzare le librerie client supportate senza l'interfaccia di conferma. Tuttavia, in questi casi, i fallimenti di conferma possono portare a re-importazioni silenziose dei messaggi.
Le librerie client supportate hanno interfacce per impostare il tempo minimo di proroga del lease (ad es. Go). Devi impostare il valore dell'estensione minima del lease su un numero elevato per evitare la scadenza dei riconoscimenti relativi alla rete. Il valore massimo è impostato su 600 secondi.
I valori e l'intervallo predefiniti per le variabili relative all'invio esattamente una volta e i nomi delle variabili potrebbero variare tra le librerie client. Ad esempio, nella libreria client Java, le seguenti variabili controllano la pubblicazione esattamente una volta.
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 per l'acknowledgment della modifica. | Intervallo=da 0 a 600. Valore predefinito=nessuno |
maxDurationPerAckExtension |
Il tempo massimo in secondi da utilizzare per estendere la scadenza per l'accettazione della modifica. | Intervallo=da 0 a 600. Valore predefinito=nessuno |
Nel caso di invio esattamente una volta, la richiesta modifyAckDeadline
o acknowledgment
a Pub/Sub non va a buon fine quando l'ID di conferma è già scaduto. In questi casi, il servizio considera l'ID di conferma scaduto non valido, poiché una spedizione più recente potrebbe essere già in corso. Questo è previsto per l'invio esattamente una volta. Vedrai quindi che le richieste acknowledgment
e ModifyAckDeadline
restituiscono una risposta INVALID_ARGUMENT
. Quando la consegna esattamente una volta è disattivata, queste richieste restituiscono OK
in caso di ID di conferma scaduti.
Per assicurarti che le richieste acknowledgment
e ModifyAckDeadline
abbiano ID di conferma validi, ti consigliamo di impostare il valore di minDurationPerAckExtension
su un numero elevato.
Considerazioni regionali
La garanzia di consegna "exactly-once" si applica solo quando gli abbonati si connettono al servizio nella stessa regione. Se l'applicazione degli abbonati è distribuita su più regioni, può verificarsi la consegna di messaggi duplicati, anche quando è attivata la consegna esattamente una volta. I publisher possono inviare messaggi a qualsiasi regione e la garanzia di invio esattamente una volta viene comunque mantenuta.
Quando esegui l'applicazione in Google Cloud, per impostazione predefinita si connette all'endpoint Pub/Sub nella stessa regione. Pertanto, eseguire l'applicazione in una singola regione in Google Cloud garantisce in genere che stai interagendo con una singola regione.
Quando esegui l'applicazione di abbonamento al di fuori di Google Cloud o in più regioni, puoi assicurarti di connetterti a una singola regione utilizzando un endpoint geografico durante la configurazione del client Pub/Sub. Tutti gli endpoint di località per Pub/Sub rimandano a singole regioni. Per scoprire di più sugli endpoint geografici, consulta Endpoint Pub/Sub. Per un elenco di tutti gli endpoint geografici per Pub/Sub, consulta Elenco di endpoint geografici.
Creare abbonamenti con consegna "exactly-once"
Puoi creare una sottoscrizione con invio esattamente una volta utilizzando la console Google Cloud, Google Cloud CLI, la libreria client o l'API Pub/Sub.
Sottoscrizione pull
Console
Per creare un abbonamento pull con invio esattamente una volta:
Nella console Google Cloud, vai alla pagina Abbonamenti.
Fai clic su Crea sottoscrizione.
Inserisci l'ID abbonamento.
Scegli o crea un argomento dal menu a discesa.
La sottoscrizione riceve i messaggi dall'argomento.
Nella sezione Consegna "exactly-once", seleziona Attiva la consegna "exactly-once".
Fai clic su Crea.
gcloud
Per creare una sottoscrizione pull con la modalità exactly-once, utilizza il comando
gcloud pubsub subscriptions create
con il flag --enable-exactly-once-delivery
:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
Sostituisci quanto segue:
- SUBSCRIPTION_ID: l'ID dell'abbonamento da creare
- TOPIC_ID: l'ID dell'argomento da associare all'abbonamento
REST
Per creare un abbonamento con invio esattamente una volta, utilizza il metodo
projects.subscriptions.create
.
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 del progetto in cui creare l'abbonamento
- SUBSCRIPTION_ID: l'ID dell'abbonamento da creare
Per creare una sottoscrizione pull con invio esattamente una volta, specifica quanto segue nel corpo della richiesta:
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
Sostituisci quanto segue:
- PROJECT_ID: l'ID del progetto con l'argomento
- TOPIC_ID: l'ID dell'argomento da associare all'abbonamento
C++
Prima di provare questo esempio, segui le istruzioni di configurazione C++ riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C++.
C#
Prima di provare questo esempio, segui le istruzioni di configurazione C# riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C#.
Vai
Prima di provare questo esempio, segui le istruzioni di configurazione di Go riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Go.
Java
Prima di provare questo esempio, segui le istruzioni di configurazione di Java riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Java Pub/Sub.
Python
Prima di provare questo esempio, segui le istruzioni di configurazione di Python riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub per Python.
Node.js
Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js riportate nella Guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, 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 riportate nella Guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Ruby
Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Ruby Pub/Sub.
PHP
Prima di provare questo esempio, segui le istruzioni di configurazione di PHP riportate nella guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API PHP Pub/Sub.
Abbonarsi con la consegna dei messaggi "exactly-once"
Di seguito sono riportati alcuni esempi di codice per l'iscrizione con invio esattamente una volta utilizzando la libreria client.
Sottoscrizione pull
Go
Prima di provare questo esempio, segui le istruzioni di configurazione di Go riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Go.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Java
Prima di provare questo esempio, segui le istruzioni di configurazione di Java riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Java.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Node.js
Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
PHP
Prima di provare questo esempio, segui le istruzioni di configurazione di PHP riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub PHP.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Python
Prima di provare questo esempio, segui le istruzioni di configurazione di Python riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Python.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Ruby
Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Ruby.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
C++
Prima di provare questo esempio, segui le istruzioni di configurazione di C++ riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C++.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
C#
Prima di provare questo esempio, segui le istruzioni di configurazione di C# riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C#.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Node.js (TypeScript)
Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js riportate nella guida rapida di Pub/Sub che utilizza le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Per autenticarti a Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Monitorare le iscrizioni alla consegna "exactly-once"
La metrica
subscription/exactly_once_warning_count
registra il numero di eventi che
possono comportare possibili reimportazioni (valide o duplicate). Questa metrica conteggia le volte in cui Pub/Sub non riesce a elaborare le richieste associate agli ID di conferma (richiesta ModifyAckDeadline
o acknowledgment
). I motivi
dell'errore possono essere basati sul server o sul client. Ad esempio, se il livello di persistenza utilizzato per mantenere le informazioni di invio esattamente una volta non è disponibile, si tratta di un evento basato su server. Se il client tenta di confermare un messaggio con un ID conferma non valido, si tratta di un evento basato sul client.
Informazioni sulla metrica
subscription/exactly_once_warning_count
acquisisce eventi che potrebbero o meno portare a caricamenti effettivi e può essere poco affidabile in base al comportamento del client. Ad esempio, richieste acknowledgment
o ModifyAckDeadline
ripetute con ID di conferma non validi incrementano la metrica ripetutamente.
Le seguenti metriche sono utili anche per comprendere il comportamento dei clienti:
subscription/expired_ack_deadlines_count
La metrica mostra il numero di scadenze degli ID di conferma. La scadenza dell'ID conferma può comportare errori sia per le richiesteModifyAckDeadline
sia per quelleacknowledgment
.La metrica
service.serviceruntime.googleapis.com/api/request_count
può essere utilizzata per rilevare gli errori delle richiesteModifyAckDeadline
oacknowledgment
nei casi in cui le richieste raggiungono Google Cloud, ma non raggiungono Pub/Sub. 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 per i quali è possibile riprovare, 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 consumati dagli abbonamenti con la consegna esattamente una volta attivata per regione.
- Numero di messaggi confermati o la cui scadenza è stata estesa quando si utilizzano i suddetti abbonamenti con la consegna "exactly-once" abilitata per regione.
Per ulteriori informazioni su queste quote, consulta la tabella nell'argomento Quote.
Consegna "exactly-once" e iscrizioni ordinate
Pub/Sub supporta la consegna "exactly-once" con la consegna in ordine.
Quando utilizzi l'ordinamento con la consegna "exactly-once", Pub/Sub si aspetta che i riconoscimenti siano in ordine. Se i riconoscimenti non sono in ordine, il servizio non riesce a soddisfare le richieste con errori temporanei. Se la scadenza della conferma scade prima di una conferma in ordine per la consegna, il cliente riceverà una nuova consegna del messaggio. Per questo motivo, quando utilizzi l'ordinamento con la consegna esattamente una volta, il throughput del client è limitato a un ordine di migliaia di messaggi al secondo.
Consegna "exactly-once" e iscrizioni push
Pub/Sub supporta la consegna "exactly-once" solo con le sottoscrizioni pull.
I client che utilizzano i messaggi dagli abbonamenti push li confermano rispondendo alle richieste push con una risposta positiva. Tuttavia, i client non sanno se l'abbonamento Pub/Sub ha ricevuto la risposta e la ha elaborata. Questo è diverso dalle iscrizioni pull, in cui le richieste di conferma vengono avviate dai client e l'abbonamento Pub/Sub risponde se la richiesta è stata elaborata correttamente. Per questo motivo, la semantica di consegna "exactly-once" non è molto in linea con le iscrizioni push.
Aspetti da tenere presenti
Se la scadenza per la conferma non viene specificata al momento della creazione della sottoscrizione, le sottoscrizioni con la consegna "exactly-once" abilitata avranno una scadenza predefinita per la conferma di 60 secondi.
Scadenza di conferma predefinite più lunghe sono utili per evitare la reimportazione causata da eventi di rete. Le librerie client supportate non utilizzano la scadenza predefinita per il riconoscimento della sottoscrizione.
Le sottoscrizioni con consegna "exactly-once" hanno una latenza dalla pubblicazione alla sottoscrizione molto più elevata rispetto alle sottoscrizioni normali.
Se hai bisogno di una maggiore velocità in uscita, i client di importazione esattamente una volta devono utilizzare anche lo streaming pull.
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 unici da parte del client di pubblicazione o del servizio Pub/Sub. Più pubblicazioni univoche del client di pubblicazione, durante i tentativi, comportano nuove importazioni con ID messaggio diversi. Più pubblicazioni univoche 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 riprovano automaticamente. Tuttavia, non è possibile riprovare per gli errori relativi a ID di conferma non validi.