Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Utilisez une file d’attente qui agit comme une mémoire tampon entre une tâche et le service qu’elle appelle. Cette approche lisse les charges intensives intermittentes qui peuvent entraîner l’échec du service ou l’expiration de la tâche. Elle permet de réduire l’effet des pics de demande sur la disponibilité et la réactivité de la tâche et du service.
Contexte et problème
De nombreuses solutions dans le cloud exécutent des tâches qui appellent des services. Dans cet environnement, les charges lourdes intermittentes peuvent entraîner des problèmes de performances ou de fiabilité pour un service.
Un service peut faire partie de la même solution que les tâches qui l’utilisent, ou il peut s’agir d’un service partenaire qui fournit l’accès aux ressources fréquemment utilisées. Par exemple, ces types de services incluent un cache ou un service de stockage. Lorsque plusieurs tâches s’exécutent simultanément et utilisent le même service, il est difficile de prédire le volume de requêtes à tout moment.
Un service peut rencontrer des pics de demande qui le surchargent et rendent le service incapable de répondre rapidement aux demandes. L’inondation d’un service avec de nombreuses requêtes simultanées peut également entraîner l’échec du service s’il ne peut pas gérer la contention que ces demandes provoquent.
Solution
Placez une file d’attente entre la tâche et le service. La tâche et le service s’exécutent de façon asynchrone. La tâche publie dans la file d’attente un message contenant les données requises par le service. La file d’attente agit en tant que mémoire tampon et stocke le message jusqu’à ce que le service le récupère. Le service récupère les messages de la file d’attente et les traite. Les demandes de plusieurs tâches, qui peuvent être générées à des taux très variables, peuvent être transmises au service via la même file d’attente de messages. Le diagramme suivant montre comment une file d’attente peut niveaur la charge sur un service.
La file d’attente dissocie les tâches du service afin que le service puisse gérer les messages à son propre rythme, même lorsque les tâches simultanées génèrent un volume élevé de requêtes. En outre, les tâches ne sont pas retardées si le service n’est pas disponible lorsqu’ils publient des messages dans la file d’attente.
Ce modèle permet de bénéficier des avantages suivants :
Cela permet d’optimiser la disponibilité, car les retards de service n’affectent pas immédiatement et directement l’application. L’application peut continuer à publier des messages dans la file d’attente même si le service n’est pas disponible ou n’est pas en cours de traitement des messages.
Il permet d’optimiser l’évolutivité, car le nombre de files d’attente et le nombre de services peuvent varier pour répondre à la demande.
Cela permet de contrôler les coûts, car vous n’avez besoin que d’instances de service suffisantes pour répondre aux exigences d’une charge moyenne plutôt que de la charge maximale.
Note
Certains services implémentent la limitation lorsque la demande atteint un seuil susceptible d’entraîner une défaillance du système. Le bridage peut réduire les fonctionnalités disponibles. Implémentez le nivellement de charge dans ces services pour vous assurer que la demande n’atteint pas ce seuil.
Problèmes et considérations
Tenez compte des points suivants lorsque vous décidez comment implémenter ce modèle :
Implémentez la logique d’application qui contrôle le taux auquel les services gèrent les messages pour éviter d’accablant la ressource cible. Évitez de transférer des pics de demande à l’étape suivante du système. Testez le système sous charge pour vous assurer qu’il assure la mise à niveau requise. Pour atteindre le niveau requis, ajustez le nombre de files d’attente et le nombre d’instances de service qui gèrent les messages.
Les files d’attente de messages constituent un mécanisme de communication unidirectionnelle. Si une tâche attend une réponse d’un service, vous devrez peut-être implémenter un mécanisme que le service peut utiliser pour envoyer une réponse. Pour plus d’informations, consultez les options de messagerie asynchrone dans Azure.
La mise à l’échelle automatique sans plafonner le débit cumulé vers l’aval des consommateurs ne fait que déplacer la surcharge vers les dépendances en aval. Cette surcharge peut accroître la concurrence pour les ressources partagées par ces services et diminuer l’efficacité de la file d’attente pour lisser la charge.
Si votre taux de production moyen dépasse le taux de consommation, la file d’attente continue de croître et la latence augmente. Surveillez la longueur de la file d’attente et augmentez ou réduisez le nombre de consommateurs dans des limites sûres, ou réduisez la charge côté producteur.
Ce modèle dépend de la durabilité de la file d’attente pour éviter la perte de messages. Si le répartiteur ne conserve pas les messages dans un stockage durable, un blocage ou une limite de capacité peut entraîner la perte des données en file d’attente avant que les consommateurs ne le traitent. Choisissez un service de file d’attente qui conserve les messages sur le disque ou le stockage répliqué, et comprenez ses quotas de taille et ses limites de rétention. Pour les charges de travail qui nécessitent des messages pour survivre aux défaillances régionales, évaluez les options de géorécupération d’urgence.
La plupart des services de file d’attente fournissent des messages avec une sémantique au moins une fois, ce qui signifie que les consommateurs peuvent recevoir le même message plusieurs fois. Concevez la logique du consommateur de manière à la rendre idempotente, afin que le traitement du même message à plusieurs reprises produise le même résultat et évite des problèmes tels que des enregistrements en double ou des facturations répétées.
Certains messages ne peuvent pas être traités, car ils contiennent des données incorrectes, référencent des ressources manquantes ou déclenchent des erreurs persistantes. Au lieu de laisser ces messages tourner en boucle indéfiniment et bloquer la file d’attente, redirigez-les vers une file d’attente de messages morts. Surveillez la taille de la file de lettres mortes afin que votre équipe d’exploitation puisse analyser les échecs, corriger le problème sous-jacent et renvoyer les messages le cas échéant.
L’introduction d’une file d’attente entre un producteur et un consommateur ne conserve pas l’ordre de soumission d’origine dans toutes les conditions, en particulier lorsque plusieurs consommateurs traitent des messages en parallèle. Si votre charge de travail nécessite un ordre strict, utilisez des fonctionnalités telles que des sessions message dans Azure Service Bus. Si un ordre strict n’est pas nécessaire, concevez les consommateurs pour qu’ils puissent traiter les messages dans n’importe quel ordre, ce qui simplifie la montée en charge.
Quand utiliser ce modèle
Utilisez ce modèle dans les situations suivantes :
Vos charges de travail rencontrent des pics intermittents qui peuvent surcharger les services en aval.
Vous devez dissocier l’entrée des demandes du débit de traitement pour améliorer la résilience et le contrôle des coûts.
Ce modèle peut ne pas convenir lorsque :
L’appelant nécessite une réponse synchrone à faible latence.
Le volume de charge de travail est prévisiblement faible et stable, de sorte que l’ajout de la complexité de la file d’attente offre peu d’avantages.
Conception de la charge de travail
Évaluez comment utiliser le modèle de nivellement de charge basé sur une file d’attente dans la conception d’une charge de travail afin de répondre aux objectifs et aux principes décrits dans les piliers du Azure Well-Architected Framework. Le tableau suivant fournit des conseils sur la façon dont ce modèle prend en charge les objectifs de chaque pilier.
| Pilier | Comment ce modèle soutient les objectifs des piliers. |
|---|---|
| Les décisions de conception de fiabilité aident votre charge de travail à devenir résiliente au dysfonctionnement et à s’assurer qu’elle se rétablit dans un état entièrement opérationnel après une défaillance. | L’approche décrite par ce modèle peut fournir une résilience contre les pics soudains de demande en découplant l’arrivée des tâches de leur traitement. Il peut également isoler les dysfonctionnements dans le traitement de la file d’attente afin qu’ils n’affectent pas l’entrée. - RE:06 Mise à l’échelle |
| L’optimisation des coûts se concentre sur le maintien et l’amélioration du retour sur investissement de votre charge de travail. | Étant donné que le traitement de la charge est découplé de la réception des demandes ou tâches, vous pouvez utiliser cette approche pour réduire le besoin de surdimensionner les ressources pour gérer la charge de pointe. - CO:12 Coûts de mise à l’échelle |
| L’efficacité des performances permet à votre charge de travail de répondre efficacement aux demandes par le biais d’optimisations de la mise à l’échelle, des données et du code. | Cette approche permet de concevoir délibérément les performances de débit, car la réception des requêtes n’a pas besoin d’être corrélée à la cadence de traitement. - PE :05 Mise à l’échelle et partitionnement |
Si ce modèle introduit des compromis au sein d’un pilier, considérez-les contre les objectifs des autres piliers.
Exemple
Une application web écrit des données dans un magasin de données externes. Si plusieurs instances de l’application web s’exécutent en parallèle, le stockage de données peut ne pas être en mesure de répondre assez rapidement aux requêtes, ce qui peut entraîner leur expiration, une limitation de débit ou un autre type d’échec. Le diagramme suivant montre un magasin de données submergé par les requêtes simultanées d’instances d’une application.
Pour résoudre ce problème, utilisez une file d’attente pour niveaur la charge entre les instances de l’application et le magasin de données. Une application Azure Functions lit les messages d’une file d’attente Service Bus et effectue les demandes de lecture/écriture dans le magasin de données. Azure Functions peut mettre à l’échelle des instances en fonction de l’arriéré de Service Bus à l’aide de la mise à l’échelle basée sur la cible, dans les limites de mise à l’échelle que vous avez configurées. Vous pouvez également ajuster les paramètres de concurrence du déclencheur pour protéger le stockage de données. Pour obtenir des conseils d’implémentation, consultez La mise à l’échelle basée sur la cible et limiter le scale-out. Sans ce réglage, la couche Worker peut réintroduire la contention back-end.
En tant que variante technologique, vous pouvez implémenter le même modèle à l’aide de Azure Container Apps au lieu de Azure Functions. Dans cette approche, un processus conteneurisé consomme des messages de Service Bus et écrit dans le magasin de données. Container Apps fait évoluer le nombre de réplicas du worker entre les valeurs minimale et maximale configurées, en fonction des règles de mise à l’échelle liées à la file d’attente. Vous pouvez également implémenter la même approche à l’aide de Stockage File d'attente Azure comme source d’événement. Pour obtenir des conseils d’implémentation, consultez Définir des règles de mise à l’échelle dans Container Apps et Déployer un travail piloté par les événements à l’aide de Container Apps.
Étapes suivantes
Les conseils suivants peuvent également être pertinents lors de l’implémentation de ce modèle :
Options de messagerie asynchrone dans Azure : les files d’attente sont intrinsèquement asynchrones. Vous devrez peut-être redéfinir la logique d’application d’une tâche si elle communique directement avec un service. De même, vous devrez peut-être refactoriser un service pour accepter les demandes d’une file d’attente de messages.
Choisir entre les services de messagerie Azure : obtenez davantage d’informations pour vous aider à choisir un mécanisme de messagerie et de mise en file d’attente dans les applications Azure.
Recommandations pour le développement de travaux en arrière-plan : appliquez ce modèle aux travaux en arrière-plan afin que les files d’attente de messages puissent stocker les demandes de tâches en arrière-plan lorsque l’application subit une charge élevée.
Style d’architecture Web-Queue-Worker : le composant web et le worker sont tous deux sans état. L’état de session peut être stocké dans un cache distribué. Le travail de longue durée fonctionne de manière asynchrone et peut être déclenché par des messages sur la file d’attente ou exécutés selon une planification pour le traitement par lots.
Ressources associées
Modèle consommateurs concurrents : il peut être possible d’exécuter plusieurs instances d’un service, chacune agissant en tant que consommateur de messages à partir de la file d’attente de niveau de charge. Vous pouvez utiliser cette approche pour ajuster la fréquence à laquelle les messages sont reçus et transmis à un service.
Modèle de limitation : un moyen simple d’implémenter la limitation dans un service consiste à utiliser le nivellement de charge basé sur la file d’attente et à router toutes les requêtes vers un service via une file d’attente de messages. Le service peut traiter des demandes à un débit qui garantit qu’il n’épuise pas les ressources dont il a besoin et réduit la quantité de contention possible.