Cette page explique comment recevoir et confirmer des messages à l'aide de la fonctionnalité de traitement de type "exactement une fois" de Pub/Sub, qui vous permet de suivre et d'empêcher le traitement en double des messages. Lorsque la fonctionnalité est activée, Pub/Sub fournit la sémantique suivante:
Les abonnés peuvent déterminer si les accusés de réception des messages ont réussi.
Aucune nouvelle diffusion n'est effectuée une fois le message confirmé.
Aucune nouvelle diffusion n'est effectuée tant qu'un message est en attente. Un message est considéré comme en attente jusqu'à l'expiration du délai d'accusé de réception ou jusqu'à ce que le message soit accusé de réception.
En cas de plusieurs diffusions valides, en raison de l'expiration du délai d'accusé de réception ou d'un accusé de réception négatif déclenché par le client, seul le dernier ID d'accusé de réception peut être utilisé pour accuser réception du message. Toutes les requêtes avec un ID de confirmation précédent échouent.
Lorsque le traitement "exactement une fois" est activé, les abonnés peuvent s'assurer que les messages sont traités une seule fois en suivant ces consignes:
Confirmez les messages dans le délai de confirmation.
Conservez les informations sur l'avancement du traitement d'un message jusqu'à ce qu'il soit confirmé.
Utilisez les informations sur la progression du traitement d'un message pour éviter les doublons lorsque l'acquittement échoue.
Seul le type d'abonnement pull est compatible avec la distribution "exactement une fois", y compris les abonnés qui utilisent l'API StreamingPull. Les abonnements push et d'exportation ne sont pas compatibles avec la distribution de type "exactement une fois".
Pub/Sub prend en charge la distribution de type "exactement une fois", dans une région cloud, sur la base d'un ID de message unique défini par Pub/Sub.
Versions de bibliothèque cliente recommandées
- Pour de meilleures performances, utilisez la dernière version de la bibliothèque cliente, Python v2.13.6 ou version ultérieure, Java v1.120.11 ou version ultérieure, PHP v1.39.0 ou version ultérieure, C# v3.2.0 ou version ultérieure, C++ v2.1.0, Go v1.25.1 ou version ultérieure, Node v3.2.0 ou version ultérieure et Ruby v2.12.1 ou version ultérieure.
Nouvel envoi par rapport à un doublon
Il est important de bien comprendre la différence entre les nouvelles diffusions attendues et inattendues.
Une nouvelle diffusion peut se produire en raison d'un accusé de réception négatif d'un message initié par le client ou lorsque le client ne prolonge pas le délai d'accusé de réception du message avant son expiration. Les nouvelles livraisons sont considérées comme valides et le système fonctionne comme prévu.
Pour résoudre les problèmes de nouvelle diffusion, consultez Gérer les doublons.
Un message est considéré comme un doublon lorsqu'il est renvoyé après un accusé de réception réussi ou avant l'expiration du délai d'expiration de l'accusé de réception.
Un message réexpédié conserve le même ID de message entre les tentatives de réexpédition.
Les abonnements pour lesquels la distribution de type "exactement une fois" est activée ne reçoivent pas de diffusions en double.
Compatibilité avec la distribution de type "exactement une fois" dans les bibliothèques clientes
Les bibliothèques clientes compatibles disposent d'une interface pour l'acquittement avec réponse (par exemple, Go). Vous pouvez utiliser cette interface pour vérifier si la requête d'acquittement a réussi. Si la requête d'acquittement aboutit, les clients ne reçoivent pas de nouvelle diffusion. Si la requête de confirmation échoue, les clients peuvent s'attendre à une nouvelle livraison.
Les clients peuvent également utiliser les bibliothèques clientes compatibles sans l'interface d'acquittement. Toutefois, dans ce cas, les échecs de confirmation peuvent entraîner des nouvelles diffusions silencieuses des messages.
Les bibliothèques clientes compatibles disposent d'interfaces permettant de définir la durée minimale de prolongation du bail (par exemple, Go). Vous devez définir la valeur de l'extension de bail minimale sur un nombre élevé pour éviter toute expiration de l'acquittement liée au réseau. La valeur maximale est définie sur 600 secondes.
Les valeurs et la plage par défaut des variables liées à la diffusion exactement une fois, ainsi que les noms des variables, peuvent varier d'une bibliothèque cliente à l'autre. Par exemple, dans la bibliothèque cliente Java, les variables suivantes contrôlent la diffusion exactement une fois.
Variable | Description | Valeur |
---|---|---|
setEnableExactlyOnceDelivery |
Active ou désactive la distribution de type "exactement une fois". | "true" ou "false" (par défaut : "false") |
minDurationPerAckExtension |
Durée minimale (en secondes) à utiliser pour prolonger le délai de confirmation de la modification. | Plage : 0 à 600 ; valeur par défaut : aucune |
maxDurationPerAckExtension |
Durée maximale (en secondes) à utiliser pour prolonger le délai de confirmation de la modification. | Plage : 0 à 600 Valeur par défaut : aucune |
En cas de distribution de type "exactement une fois", la requête modifyAckDeadline
ou acknowledgment
envoyée à Pub/Sub échoue lorsque l'ID d'acquittement a déjà expiré. Dans ce cas, le service considère l'ID de confirmation expiré comme non valide, car une diffusion plus récente est peut-être déjà en cours. Cela est volontaire pour la diffusion "exactement une fois". Vous voyez ensuite que les requêtes acknowledgment
et ModifyAckDeadline
renvoient une réponse INVALID_ARGUMENT
. Lorsque la diffusion de type "exactement une fois" est désactivée, ces requêtes renvoient OK
en cas d'ID de confirmation expirés.
Pour vous assurer que les requêtes acknowledgment
et ModifyAckDeadline
disposent d'ID de confirmation valides, envisagez de définir la valeur de minDurationPerAckExtension
sur un nombre élevé.
Points à prendre en compte concernant les régions
La garantie de distribution de type "exactement une fois" ne s'applique que lorsque les abonnés se connectent au service dans la même région. Si votre application d'abonné est répartie sur plusieurs régions, cela peut entraîner la distribution de messages en double, même lorsque la distribution de type "exactement une fois" est activée. Les éditeurs peuvent envoyer des messages dans n'importe quelle région, et la garantie d'envoi exact est toujours maintenue.
Lorsque vous exécutez votre application dans Google Cloud, elle se connecte par défaut au point de terminaison Pub/Sub de la même région. Par conséquent, exécuter votre application dans une seule région de Google Cloud vous garantit généralement d'interagir avec une seule région.
Lorsque vous exécutez votre application d'abonné en dehors de Google Cloud ou dans plusieurs régions, vous pouvez vous assurer de vous connecter à une seule région à l'aide d'un point de terminaison géographique lorsque vous configurez votre client Pub/Sub. Tous les points de terminaison d'emplacement pour Pub/Sub pointent vers des régions uniques. Pour en savoir plus sur les points de terminaison géographiques, consultez la section Points de terminaison Pub/Sub. Pour obtenir la liste de tous les points de terminaison localisés pour Pub/Sub, consultez la section Liste des points de terminaison localisés.
Créer des abonnements avec la distribution de type "exactement une fois"
Vous pouvez créer un abonnement avec une diffusion exactement une fois à l'aide de la console Google Cloud, de la Google Cloud CLI, de la bibliothèque cliente ou de l'API Pub/Sub.
Abonnement pull
Console
Pour créer un abonnement pull avec envoi exactement une fois, procédez comme suit:
Dans la console Google Cloud, accédez à la page Abonnements.
Cliquez sur Créer un abonnement.
Saisissez l'ID de l'abonnement.
Choisissez ou créez un sujet dans le menu déroulant.
L'abonnement reçoit les messages du sujet.
Dans la section Distribution de type "exactement une fois", sélectionnez Activer la distribution de type "exactement une fois".
Cliquez sur Créer.
gcloud
Pour créer un abonnement pull avec une diffusion exactement une fois, exécutez la commande gcloud pubsub subscriptions create
avec l'option --enable-exactly-once-delivery
:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
Remplacez les éléments suivants :
- SUBSCRIPTION_ID : ID de l'abonnement à créer
- TOPIC_ID : ID du sujet à associer à l'abonnement
REST
Pour créer un abonnement avec une distribution "exactly-once", utilisez la méthode projects.subscriptions.create
.
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
Remplacez les éléments suivants :
- PROJECT_ID : ID du projet dans lequel créer l'abonnement
- SUBSCRIPTION_ID : ID de l'abonnement à créer
Pour créer un abonnement pull avec une distribution "exactly-once", spécifiez-le dans le corps de la requête:
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
Remplacez les éléments suivants :
- PROJECT_ID : ID du projet contenant le sujet.
- TOPIC_ID : ID du sujet à associer à l'abonnement
C++
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage C++ qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour C++.
C#
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage C# qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour C#.
Go
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Go qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Go.
Java
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Java qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Java.
Python
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Python qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Python.
Node.js
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Node.js qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Node.js.
Node.js
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Node.js qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Node.js.
Ruby
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage Ruby qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Ruby.
PHP
Avant d'essayer cet exemple, suivez les instructions d'installation dans le langage PHP qui se trouvent sur la page Démarrage rapide : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour PHP.
S'abonner avec la distribution de messages de type "exactement une fois"
Vous trouverez ci-dessous quelques exemples de code pour vous abonner avec une diffusion exactement une fois à l'aide de la bibliothèque cliente.
Abonnement pull
Go
Avant d'essayer cet exemple, suivez les instructions de configuration pour Go du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub Go.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Java
Avant d'essayer cet exemple, suivez les instructions de configuration pour Java du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub Java.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Node.js
Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub Node.js.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
PHP
Avant d'essayer cet exemple, suivez les instructions de configuration pour PHP du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub PHP.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Python
Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub Python.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Ruby
Avant d'essayer cet exemple, suivez les instructions de configuration pour Ruby du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub Ruby.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
C++
Avant d'essayer cet exemple, suivez les instructions de configuration pour C++ du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub C++.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
C#
Avant d'essayer cet exemple, suivez les instructions de configuration pour C# du guide de démarrage rapide de Pub/Sub : utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub C#.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Node.js (TypeScript)
Avant d'essayer cet exemple, suivez les instructions de configuration de Node.js décrites dans le guide de démarrage rapide de Pub/Sub : utiliser des bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API Pub/Sub pour Node.js.
Pour vous authentifier auprès de Pub/Sub, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Surveiller les abonnements de diffusion de type "exactement une fois"
La métrique subscription/exactly_once_warning_count
enregistre le nombre d'événements pouvant entraîner des nouvelles diffusions (valides ou en double). Cette métrique compte les cas où Pub/Sub ne parvient pas à traiter les requêtes associées aux ID de confirmation (requête ModifyAckDeadline
ou acknowledgment
). Les raisons de l'échec peuvent être liées au serveur ou au client. Par exemple, si la couche de persistance utilisée pour gérer les informations de diffusion "exactement une fois" n'est pas disponible, il s'agit d'un événement basé sur le serveur. Si le client tente de confirmer un message avec un ID de confirmation non valide, il s'agit d'un événement basé sur le client.
Comprendre la métrique
subscription/exactly_once_warning_count
capture les événements qui peuvent ou non entraîner des nouvelles diffusions et peut être bruyant en fonction du comportement du client. Par exemple, les requêtes acknowledgment
ou ModifyAckDeadline
répétées avec des ID de confirmation non valides incrémentent la métrique à plusieurs reprises.
Les métriques suivantes sont également utiles pour comprendre le comportement des clients:
La métrique
subscription/expired_ack_deadlines_count
indique le nombre d'expirations d'ID de confirmation. L'expiration des ID de confirmation peut entraîner des échecs pour les requêtesModifyAckDeadline
etacknowledgment
.La métrique
service.serviceruntime.googleapis.com/api/request_count
peut être utilisée pour capturer les échecs des requêtesModifyAckDeadline
ouacknowledgment
lorsque les requêtes atteignent Google Cloud, mais pas Pub/Sub. Il existe des échecs que cette métrique ne capturera pas, par exemple lorsque les clients sont déconnectés de Google Cloud.
Dans la plupart des cas d'événements d'échec pouvant être réessayés, les bibliothèques clientes compatibles relancent automatiquement la requête.
Quotas
Les abonnements de distribution de type "exactement une fois" sont soumis à des exigences de quota supplémentaires. Ces quotas s'appliquent aux éléments suivants:
- Nombre de messages consommés à partir d'abonnements avec la distribution de type "exactement une fois" activée par région.
- Nombre de messages confirmés ou dont la date limite est prolongée lorsque vous utilisez des abonnements avec la distribution "exactement une fois" activée par région.
Pour en savoir plus sur ces quotas, consultez le tableau de la section Quotas.
Diffusion de type "exactement une fois" et abonnements ordonnés
Pub/Sub est compatible avec la distribution de type "exactement une fois" avec la distribution ordonnée.
Lorsque vous utilisez la distribution de type "exactement une fois", Pub/Sub s'attend à ce que les accusés de réception soient dans l'ordre. Si les accusés de réception sont dans le désordre, le service échoue les requêtes avec des erreurs temporaires. Si le délai de confirmation expire avant qu'un accusé de réception dans l'ordre de livraison ne soit reçu, le client recevra une nouvelle diffusion du message. Par conséquent, lorsque vous utilisez la commande avec une distribution exactement une fois, le débit client est limité à un ordre de mille messages par seconde.
Diffusion de type "exactement une fois" et abonnements push
Pub/Sub n'est compatible avec la distribution de type "exactement une fois" que pour les abonnements pull.
Les clients qui consomment des messages provenant des abonnements push confirment les messages en répondant aux requêtes push par une réponse de réussite. Toutefois, les clients ne savent pas si l'abonnement Pub/Sub a reçu la réponse et l'a traitée. Cela diffère des abonnements pull, où les requêtes d'acquittement sont lancées par les clients et que l'abonnement Pub/Sub répond si la requête a bien été traitée. Par conséquent, la sémantique de distribution de type "exactement une fois" ne correspond pas bien aux abonnements push.
Bon à savoir
Si le délai d'expiration de l'accusé de réception n'est pas spécifié au moment de la création de l'abonnement, le délai d'expiration de l'accusé de réception par défaut est de 60 secondes pour les abonnements pour lesquels la diffusion de type "exactement une fois" est activée.
Les délais de confirmation par défaut plus longs sont utiles pour éviter la nouvelle diffusion causée par des événements réseau. Les bibliothèques clientes compatibles n'utilisent pas le délai de confirmation d'abonnement par défaut.
Les abonnements de distribution de type "exactement une fois" ont une latence de publication vers l'abonnement nettement plus élevée que les abonnements standards.
Si vous avez besoin d'un débit élevé, vos clients de diffusion "exactement une fois" doivent également utiliser le flux pull.
Un abonnement peut recevoir plusieurs copies du même message en raison de doublons côté publication, même si la diffusion de type "exactement une fois" est activée. Les doublons côté publication peuvent être dus à plusieurs tentatives de publication uniques par le client de publication ou le service Pub/Sub. Plusieurs publications uniques par le client de publication, lors des nouvelles tentatives, entraînent des nouvelles diffusions avec différents ID de message. La publication unique multiple du service Pub/Sub pour répondre à une requête de publication client entraîne des nouvelles diffusions avec les mêmes ID de message.
Vous pouvez réessayer les échecs dans
subscription/exactly_once_warning_count
, et les bibliothèques clientes compatibles les réessaient automatiquement. Toutefois, les échecs liés à des ID de confirmation non valides ne peuvent pas être réessayés.