Questa pagina spiega come ricevere e riconoscere i messaggi utilizzando la funzionalità exactly-once di Pub/Sub, che 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 le conferme di lettura dei messaggi sono andate a buon fine.
Non viene eseguita alcuna nuova consegna dopo la conferma della ricezione del messaggio.
Non viene eseguita alcuna nuova consegna mentre un messaggio è in sospeso. Un messaggio è considerato in sospeso fino alla scadenza del termine di conferma o fino a quando non viene confermato.
In caso di più consegne valide, a causa della scadenza del termine di conferma o della conferma negativa avviata dal client, per confermare il messaggio può essere utilizzato solo l'ID di conferma più recente. Tutte le richieste con un ID di conferma precedente non vanno a buon fine.
Con l'elaborazione exactly-once attivata, gli abbonati possono assicurarsi che i messaggi vengano elaborati una sola volta seguendo queste linee guida:
Confermare i messaggi entro la scadenza di conferma.
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 un riconoscimento non va a buon fine.
Solo il tipo di sottoscrizione pull supporta la distribuzione esattamente una volta, 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 consigliate della libreria client
- Per ottenere le prestazioni migliori, utilizza l'ultima versione della libreria client, Python v2.13.6 o successive, Java v1.139.0 o successive, PHP v1.39.0 o successive, C# v3.2.0 o successive, C++ v2.1.0, Go v1.25.1 o successive, Node v3.2.0 o successive e Ruby v2.12.1 o successive.
Ricaricamento e duplicato
È importante comprendere la differenza tra le riproposte previste e quelle impreviste.
Una nuova consegna può avvenire a causa di una 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 che scada. Le nuove consegne sono considerate valide e il sistema funziona come previsto.
Per risolvere i problemi relativi alle nuove consegne, vedi Gestione dei duplicati.
Un duplicato si verifica quando un messaggio viene inviato nuovamente 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 con risposta (ad esempio, Go). Puoi utilizzare questa interfaccia per verificare se la richiesta di riconoscimento è andata a buon fine. Se la richiesta di riconoscimento va a buon fine, è garantito che i client non riceveranno una nuova consegna. 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 riconoscimento. Tuttavia, in questi casi, i mancati riconoscimenti possono portare a nuove distribuzioni silenziose dei messaggi.
Le librerie client supportate hanno interfacce per impostare il tempo minimo di estensione del lease (esempio: Go). Devi impostare il valore dell'estensione minima del lease su un numero elevato per evitare la scadenza degli acknowledgment correlati alla rete. Il valore massimo è impostato su 600 secondi.
Se utilizzi la libreria client Java e inizializzi il tuo abbonato con un canale gRPC personalizzato utilizzando il metodo
setChannelProvider()
, ti consigliamo di impostaremaxInboundMetadataSize
su almeno 1 MB durante la creazione diTransportChannelProvider
. Per questa configurazione, puoi utilizzare il metodoInstantiatingGrpcChannelProvider.Builder.setMaxInboundMetadataSize()
oManagedChannelBuilder.maxInboundMetadataSize()
.
I valori e l'intervallo predefiniti per le variabili relative alla distribuzione esatta e i nomi delle variabili potrebbero variare a seconda delle librerie client. Ad esempio, nella libreria client Java, le seguenti variabili controllano la distribuzione esatta.
Variabile | Descrizione | Valore |
---|---|---|
setEnableExactlyOnceDelivery |
Attiva o disattiva la consegna "exactly-once". | true o false Default=false |
minDurationPerAckExtension |
Il tempo minimo in secondi da utilizzare per estendere la scadenza della conferma 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 modifica. | Intervallo=da 0 a 600. Valore predefinito=nessuno. |
Nel caso della consegna esatta, la richiesta modifyAckDeadline
o acknowledgment
a Pub/Sub non va a buon fine quando l'ID riconoscimento è già scaduto. In questi casi, il servizio considera l'ID riconoscimento scaduto come non valido, poiché una consegna più recente potrebbe essere già in corso. Questo comportamento è previsto per la
consegna 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 riconoscimento scaduti.
Per assicurarti che le richieste acknowledgment
e ModifyAckDeadline
abbiano ID riconoscimento validi, valuta la possibilità di impostare un numero elevato per minDurationPerAckExtension
.
Considerazioni regionali
La garanzia di consegna "exactly-once" si applica solo quando gli abbonati si connettono al servizio nella stessa regione. Se l'applicazione di sottoscrizione è distribuita su più regioni, può comportare la consegna duplicata dei messaggi, anche quando è abilitata la consegna exactly-once. Gli editori possono inviare messaggi a qualsiasi regione e la garanzia di invio esattamente una volta 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 geografico 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 basati sulla località, consulta Endpoint Pub/Sub. Per un elenco di tutti gli endpoint basati sulla località per Pub/Sub, consulta Elenco degli endpoint basati sulla località.
Crea abbonamenti con consegna "exactly-once"
Puoi creare una sottoscrizione con la funzionalità di 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 la funzionalità di 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 Abilita la consegna "exactly-once".
Fai clic su Crea.
gcloud
Per creare una sottoscrizione pull con la consegna 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 collegare all'abbonamento
REST
Per creare una sottoscrizione con la consegna "exactly-once", 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 progetto in cui creare l'abbonamento
- SUBSCRIPTION_ID: l'ID dell'abbonamento da creare
Per creare una sottoscrizione pull con la 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 per il progetto con l'argomento
- TOPIC_ID: l'ID dell'argomento da collegare all'abbonamento
C++
Prima di provare questo esempio, segui le istruzioni di configurazione di C++ 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 di C# 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 nella 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 nella Guida rapida all'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Java di Pub/Sub.
Python
Prima di provare questo esempio, segui le istruzioni di configurazione di Python nella 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 nella 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 nella Guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Ruby
Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby nella 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 nella guida rapida all'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub PHP.
Sottoscrivi con la consegna dei messaggi "exactly-once"
Di seguito sono riportati alcuni esempi di codice per la sottoscrizione con la funzionalità di distribuzione esattamente una volta utilizzando la libreria client.
Sottoscrizione pull
Go
Prima di provare questo esempio, segui le istruzioni di configurazione di Go nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Go.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Java
Prima di provare questo esempio, segui le istruzioni di configurazione di Java nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Java.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Node.js
Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
PHP
Prima di provare questo esempio, segui le istruzioni di configurazione di PHP nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub PHP.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Python
Prima di provare questo esempio, segui le istruzioni di configurazione di Python nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Python.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Ruby
Prima di provare questo esempio, segui le istruzioni di configurazione di Ruby nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub Ruby.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
C++
Prima di provare questo esempio, segui le istruzioni di configurazione di C++ nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub C++.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
C#
Prima di provare questo esempio, segui le istruzioni di configurazione di C# nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API Pub/Sub C#.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Node.js (TypeScript)
Prima di provare questo esempio, segui le istruzioni di configurazione di Node.js nella guida rapida di Pub/Sub per l'utilizzo delle librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Node.js.
Per eseguire l'autenticazione in Pub/Sub, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Monitorare gli abbonamenti con consegna "exactly-once"
La metrica
subscription/exactly_once_warning_count
registra il numero di eventi che
possono portare a possibili nuove consegne (valide o duplicate). Questa metrica conteggia il numero di volte in cui Pub/Sub non riesce a elaborare le richieste associate agli ID riconoscimento (richiesta ModifyAckDeadline
o acknowledgment
). I motivi
del mancato caricamento potrebbero essere basati sul server o sul client. Ad esempio, se il livello di persistenza utilizzato per gestire le informazioni di distribuzione esattamente una volta non è disponibile, si tratterebbe di un evento basato sul server. Se il client tenta di riconoscere un messaggio con
un ID riconoscimento non valido, si tratta di un evento basato sul client.
Comprendere la metrica
subscription/exactly_once_warning_count
acquisisce eventi che potrebbero o meno
portare a nuove consegne effettive e può essere rumoroso in base al comportamento del client. Ad esempio, richieste acknowledgment
o ModifyAckDeadline
ripetute con ID riconoscimento non validi aumentano ripetutamente la metrica.
Anche le seguenti metriche sono utili per comprendere il comportamento del cliente:
La metrica
subscription/expired_ack_deadlines_count
mostra il numero di scadenze dell'ID riconoscimento. La scadenza degli ID di conferma può causare errori sia per le richiesteModifyAckDeadline
che per quelleacknowledgment
.La metrica
service.serviceruntime.googleapis.com/api/request_count
può essere utilizzata per registrare gli errori delle richiesteModifyAckDeadline
oacknowledgment
nei casi in cui le richieste raggiungono Google Cloud ma non 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 che possono essere ritentati, le librerie client supportate ritentano 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 dagli abbonamenti con la funzionalità di consegna esattamente una volta abilitata per regione.
- Numero di messaggi riconosciuti o la cui scadenza è stata estesa quando si utilizzano sottoscrizioni con la 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 gli ACK siano in ordine. Se gli ACK non sono in ordine, il servizio non riesce a gestire le richieste con errori temporanei. Se la scadenza di conferma scade prima di una conferma in ordine per la consegna, il client riceverà una nuova consegna del messaggio. Per questo motivo, quando utilizzi l'ordinamento con la distribuzione esattamente una volta, la velocità effettiva del client è limitata a un ordine di mille 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 delle sottoscrizioni push confermano i messaggi rispondendo alle richieste push con una risposta positiva. Tuttavia, i client non sanno se la sottoscrizione Pub/Sub ha ricevuto la risposta e l'ha elaborata. Ciò è diverso dalle sottoscrizioni pull, in cui le richieste di riconoscimento 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 è adatta alle sottoscrizioni push.
Aspetti da tenere presenti
Se la scadenza dell'acknowledgement non viene specificata al momento di CreateSubscription, le sottoscrizioni con la consegna "exactly-once" abilitata avranno una scadenza dell'acknowledgement predefinita di 60 secondi.
Scadenze di riconoscimento predefinite più lunghe sono utili per evitare la nuova pubblicazione causata da eventi di rete. Le librerie client supportate non utilizzano la scadenza di conferma predefinita dell'abbonamento.
Le sottoscrizioni con consegna "exactly-once" hanno una latenza dalla pubblicazione alla sottoscrizione significativamente più elevata rispetto alle sottoscrizioni regolari.
Se hai bisogno di un'elevata velocità effettiva, anche i client di distribuzione exactly-once devono utilizzare 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 uniche da parte del client di pubblicazione, nei vari tentativi, comportano nuove consegne con ID messaggio diversi. Più pubblicazioni uniche da parte del servizio Pub/Sub, per rispondere a una richiesta di pubblicazione del client, comportano riconsegne con gli stessi ID messaggio.
Puoi riprovare in caso di errori in
subscription/exactly_once_warning_count
e le librerie client supportate riprovano automaticamente. Tuttavia, non è possibile riprovare in caso di errori correlati a ID di riconoscimento non validi.