Traitez un ensemble de messages connexes dans un ordre défini, sans bloquer le traitement d’autres groupes de messages.
Contexte et problème
Les applications doivent souvent traiter une séquence de messages dans leur ordre d’arrivée, tout en étant en mesure d’effectuer un scale-out pour gérer une charge accrue. Dans une architecture distribuée, le traitement de ces messages dans l’ordre n’est pas simple, car les workers peuvent être mis à l’échelle de manière indépendante et, souvent, tirer des messages indépendamment, à l’aide d’un modèle de consommateurs concurrents.
Par exemple, un système de suivi des commandes reçoit un registre contenant des commandes et les opérations pertinentes sur ces commandes. Ces opérations peuvent consister à créer une commande, ajouter une transaction à la commande, modifier une transaction passée ou supprimer une commande. Dans ce système, les opérations doivent être effectuées selon une méthode FIFO (premier entré, premier sorti), mais uniquement au niveau de la commande. Toutefois, la file d’attente initiale reçoit un registre contenant des transactions pour de nombreuses commandes, qui peuvent être entrelacées.
Solution
Envoyez (push) des messages associés à des catégories au sein du système de mise en file d’attente et faites en sorte que les écouteurs de file d’attente se verrouillent et s’extraient uniquement d’une catégorie, un message à la fois.
Voici à quoi ressemble le modèle de convoi séquentiel général :
Dans la file d’attente, les messages de différentes catégories peuvent être entrelacés, comme indiqué dans le diagramme suivant :
Problèmes et considérations
Prenez en compte les points suivants lorsque vous choisissez comment implémenter ce modèle :
- Catégorie/unité d’échelle. Quelle propriété de vos messages entrants pouvez-vous mettre à l’échelle ? Dans le scénario de suivi des commandes, cette propriété est l’ID de commande.
- Débit. Quel est le débit de vos messages cibles ? S’il s’agit d’une valeur très élevée, vous devrez peut-être reconsidérer vos exigences FIFO. Par exemple, pouvez-vous appliquer un message de début/fin, trier par heure, puis envoyer un lot pour traitement ?
- Fonctionnalités du service. Votre choix de bus de messages autorise-t-il le traitement unique des messages au sein d’une file d’attente ou d’une catégorie de file d’attente ?
- Évolutivité. Comment allez-vous ajouter une nouvelle catégorie de message au système ? Par exemple, supposons que le système de registre décrit ci-dessus soit spécifique à un client. Si vous aviez besoin d’intégrer un nouveau client, pouviez-vous avoir un ensemble de processeurs de registre qui répartissent le travail par ID client ?
- Il est possible que les contrôles serveur consommateur reçoivent un message dans le désordre, en raison d’une latence réseau variable lors de l’envoi de messages. Envisagez d’utiliser des numéros de séquence pour vérifier le classement. Vous pouvez également inclure un indicateur « fin de séquence » spécial dans le dernier message d’une transaction. Les technologies de traitement de flux, telles que Spark ou Azure Stream Analytics, peuvent traiter des messages dans l’ordre dans une fenêtre de temps.
Quand utiliser ce modèle
Utilisez ce modèle dans les situations suivantes :
- Vous avez des messages qui arrivent dans l’ordre et qui doivent être traités dans le même ordre.
- Les messages entrant sont ou peuvent être « catégorisés » de telle façon que la catégorie devienne une unité de mise à l’échelle pour le système.
Ce modèle peut ne pas convenir pour :
- des scénarios de débit extrêmement élevé (des millions de messages/minute ou seconde), étant donné que l’exigence FIFO limite la mise à l’échelle qui peut être effectuée par le système.
Conception de la charge de travail
Un architecte doit évaluer la façon dont le modèle « Convoi séquentiel » (Sequential Convoy) peut être utilisé dans la conception de leurs charges de travail pour se conformer aux objectifs et principes abordés dans les piliers d’Azure Well-Architected Framework. Par exemple :
Pilier | Comment ce modèle soutient les objectifs des piliers. |
---|---|
Les décisions relatives à la fiabilité contribuent à rendre votre charge de travail résiliente aux dysfonctionnements et à s’assurer qu’elle retrouve un état de fonctionnement optimal après une défaillance. | Ce modèle peut éliminer les conditions de concurrence difficiles à résoudre, la gestion contentieuse des messages ou d’autres solutions de contournement pour traiter les messages mal ordonnés pouvant entraîner des dysfonctionnements. - RE :02 Flux critiques - RE :07 Travaux en arrière-plan |
Comme pour toute autre décision de conception, il convient de prendre en compte les compromis par rapport aux objectifs des autres piliers qui pourraient être introduits avec ce modèle.
Exemple
Sur Azure, ce modèle peut être implémenté à l’aide des sessions de messages Azure Service Bus. Pour les consommateurs, vous pouvez utiliser Logic Apps avec le Connecteur de verrouillage d'un passage furtif Service Bus ou Azure Functions avec le déclencheur Service Bus.
Pour l’exemple de suivi de commande précédent, traitez chaque message du registre dans l’ordre de réception et envoyez chaque transaction vers une autre file d’attente dans laquelle la catégorie est définie sur l’ID de commande. Une transaction ne s’étend jamais sur plusieurs commandes dans ce scénario. Par conséquent, les contrôles serveur consommateur traite chaque catégorie en parallèle mais selon l’ordre FIFO de cette catégorie.
Le processeur de registre effectue une distribution ramifiée des messages en dégroupant le contenu de chaque message dans la première file d’attente :
Le processeur du registre s’occupe des éléments suivants :
- parcours du registre, une transaction à la fois
- définition de l’ID de session du message pour qu’il corresponde à l’ID de la commande
- envoi de chaque transaction du registre vers une file d’attente secondaire avec l’ID de session défini sur l’ID de la commande.
Les contrôles serveur consommateur écoutent la file d’attente secondaire dans laquelle ils traitent tous les messages avec des ID de commande correspondants dans l’ordre à partir de la file d’attente. Les contrôles serveur consommateur utilisent le mode verrouillage d'un passage furtif.
En matière de scalabilité, la file d’attente du registre est un goulot d’étranglement principal. Différentes transactions publiées dans le registre peuvent référencer le même ID de commande. Toutefois, les messages peuvent effectuer une distribution ramifiée après le registre pour le nombre de commandes dans un environnement serverless.
Étapes suivantes
Les informations suivantes peuvent également être pertinentes durant l’implémentation de ce modèle :