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.
Limitez les ressources qu’une instance d’application, un locataire individuel ou un service entier peut consommer. Cela permet au système de fonctionner et de répondre à ses objectifs de niveau de service (SLA) sous une charge soudaine ou soutenue.
Contexte et problème
La charge sur une application cloud varie au fil du temps en fonction des utilisateurs actifs et de leur activité. Plus d’utilisateurs se connectent pendant les heures d’ouverture et le système exécute des analyses coûteuses en calcul à la fin de chaque mois. Des rafales soudaines se produisent également. Si la demande de traitement dépasse la capacité disponible, le système ralentit ou échoue. Lorsque le système a un niveau de service convenu, cette défaillance enfreint le SLO.
Plusieurs stratégies gèrent la charge variable, en fonction des objectifs métier de l’application. Une stratégie est la mise à l’échelle automatique, qui correspond aux ressources approvisionnées à la demande actuelle et contrôle les coûts. Toutefois, l’approvisionnement de nouvelles ressources prend du temps et ajoute des coûts. La demande qui dépasse la croissance de la capacité ou le budget crée un déficit de ressources.
Solution
Une alternative à la mise à l’échelle automatique consiste à limiter l’utilisation des ressources et à limiter les demandes lorsque l’utilisation dépasse cette limite. La charge de travail surveille son propre utilisation des ressources et limite les demandes d’un ou de plusieurs utilisateurs lorsque l’utilisation dépasse le seuil. Le système continue de fonctionner et de respecter ses objectifs de niveau de service (SLO).
La limitation de débit est une boucle de contrôle, et non une décision d’admission ponctuelle. Le système a besoin de signaux à faible latence à trois couches : l’utilisation de l’infrastructure, l’état de l’application et les compteurs par principal. Il mesure en permanence la saturation, applique des limites aux limites bien définies et adapte ces limites à mesure que les modèles de trafic changent. La surcharge est un mode d’exploitation normal à partir duquel un système mature détecte et récupère. La limitation du débit offre des capacités d’auto-préservation à votre charge de travail.
Le système peut mettre en œuvre plusieurs stratégies de limitation du débit ou connexes :
Limites de taux par principal : Rejeter les demandes d’un utilisateur qui a déjà dépassé le taux configuré sur une fenêtre définie. Cette stratégie exige que le système attribue chaque requête à un principal et mesure l’utilisation des ressources pour ce principal. Pour les charges de travail mutualisées, consultez Mesurer la consommation de chaque locataire.
Dégradation des caractéristiques gracieuses : Désactivez ou dégradez les fonctionnalités nonessentiales afin que les fonctionnalités essentielles aient suffisamment de ressources. Cette stratégie échange l’exhaustivité de la réponse pour la disponibilité. Par exemple, une application de streaming vidéo peut passer à une résolution inférieure.
Niveau de charge : Volume d’activité lisse à l’aide d’une file d’attente. Dans un environnement multilocataire, le nivellement réduit les performances de chaque locataire. Lorsque les clients ont des accords de niveau de service (SLA) différents, traitez immédiatement les tâches des clients à forte valeur et mettez en attente les tâches moins prioritaires jusqu’à ce que l’arriéré s’allège. Implémentez cette approche à l’aide du modèle File d’attente prioritaire ou en exposant des points de terminaison distincts pour chaque niveau de priorité.
Report en fonction de la priorité : Différer les opérations pour le compte d’applications ou de locataires moins prioritaires. Suspendez ou limitez les opérations et retournez une exception qui indique au locataire de réessayer ultérieurement.
Limites de débit sortant : Limitez vos propres appels sortants lorsqu’une dépendance externe échoue ou retourne des erreurs. Réduisez le nombre de demandes en vol pour arrêter les journaux d’inondation et éviter les coûts de nouvelle tentative par rapport à une dépendance non saine. Restaurez le flux de requête normal après la récupération de la dépendance. Par exemple, NServiceBus implémente cette fonctionnalité.
Le graphique suivant montre l’utilisation des ressources (une combinaison de mémoire, d’UC, de bande passante et d’autres facteurs) au fil du temps pour une application qui utilise trois fonctionnalités, étiquetées A, B et C. Une fonctionnalité est une zone spécifique de fonctionnalités, telle qu’un composant qui effectue un ensemble spécifique de tâches, un élément de code qui effectue un calcul complexe ou un élément qui fournit un service tel qu’un cache en mémoire.
Un graphique en courbes trace l’utilisation des ressources sur l’axe y par rapport au temps sur l’axe x. Trois lignes colorées représentent la fonctionnalité A, la fonctionnalité B et la fonctionnalité C, avec la ligne de fonctionnalité A la plus basse, la ligne de fonctionnalité B au milieu et la ligne de fonctionnalité C la plus élevée. Une ligne horizontale solide près du haut du graphique marque la capacité maximale et une ligne horizontale en pointillés en dessous de celle-ci marque la limite réversible de l’utilisation des ressources. Deux lignes pointillées verticales marquent les temps T1 et T2. Avant T1, les courbes des trois fonctionnalités fluctuent, et la courbe de la fonctionnalité C s’élève et franchit le seuil souple. À T1, la ligne de la fonctionnalité B passe à zéro et reste à zéro jusqu’à ce que la fonctionnalité B soit suspendue pour libérer des ressources pour la fonctionnalité A et la fonctionnalité C. La ligne de fonctionnalité C tombe en dessous de la limite réversible entre T1 et T2 tandis que la fonctionnalité A continue normalement. À T2, la fonctionnalité B reprend et les trois lignes continuent de varier en dessous de la limite souple.
Le graphique est un graphique en aires empilées. La zone située sous la ligne de la fonctionnalité A montre les ressources consommées par la fonctionnalité A, la zone entre les lignes de fonctionnalité A et de fonctionnalité B montre les ressources consommées par la fonctionnalité B, et la zone entre les lignes de Fonctionnalité B et de fonctionnalité C affiche les ressources consommées par la fonctionnalité C. La ligne de la fonctionnalité C se trouve en haut de la pile, de sorte qu’elle affiche également l’utilisation totale des ressources système au fil du temps.
Le graphique montre une dégradation progressive des fonctionnalités. Juste avant le temps T1, l’utilisation totale des ressources approche du seuil et risque d’épuiser la capacité disponible. La fonctionnalité B est moins critique que la fonctionnalité A ou la fonctionnalité C. Par conséquent, le système désactive la fonctionnalité B et libère ses ressources. Entre les temps T1 et T2, la fonctionnalité A et la fonctionnalité C continuent normalement. Au moment de T2, l’utilisation totale des ressources est insuffisante pour réactiver la fonctionnalité B.
Vous pouvez combiner la mise à l’échelle automatique, la dégradation progressive et la limitation du débit pour maintenir les applications réactives et dans le respect des SLA. Lorsque vous prévoyez que la demande restera élevée, la limitation du débit maintient la stabilité pendant que le système effectue une mise à l’échelle horizontale. Une fois la mise à l’échelle terminée, le système rétablit son fonctionnement complet.
Le graphique suivant illustre l’utilisation totale des ressources au fil du temps et la façon dont la limitation du débit s’articule avec la mise à l’échelle automatique et d’autres mécanismes compensatoires.
Un graphique en courbes trace l’utilisation des ressources pour toutes les applications sur l’axe y par rapport au temps sur l’axe x. Deux lignes de référence horizontales marquent la limite réversible de l’utilisation des ressources et la capacité maximale avant la mise à l’échelle automatique. Une ligne horizontale supérieure, qui commence au moment T2, marque la capacité maximale après la mise à l’échelle automatique. La courbe du taux d’utilisation augmente et fluctue au fil du temps. Il franchit la limite souple au moment T1, qui est le point où la mise à l’échelle automatique commence. Entre T1 et T2, le système est bridé pendant la mise à l’échelle automatique, et le taux d’utilisation reste inférieur à la capacité maximale précédant la mise à l’échelle automatique. Au temps T2, la mise à l’échelle automatique se termine, le bridage est assoupli, et la courbe d’utilisation fait un bond, puis continue de fluctuer en dessous de la nouvelle capacité maximale, plus élevée.
Au moment T1, le système atteint la limite souple et commence à effectuer un scale-out. Si de nouvelles ressources ne arrivent pas dans le temps, la demande peut épuiser les ressources existantes et le système peut échouer. Le contrôle du débit rejette les requêtes excédentaires lors de la mise à l’échelle horizontale afin de maintenir l’utilisation des ressources en dessous de la limite maximale absolue, puis lève ces restrictions une fois la capacité supplémentaire disponible.
Tip
Les contrôles en périphérie et le modèle de limitation du débit répondent à des problèmes différents. Les contrôles en périphérie, tels que Azure DDoS Protection et les règles de limitation de débit du pare-feu d’applications web (WAF), s’exécutent à la périphérie du réseau et bloquent le trafic volumétrique ou malveillant avant qu’il n’atteigne votre application. Le modèle de limitation s’exécute à l’intérieur de votre application et mesure le trafic légitime par rapport aux limites définies par l’application. Utilisez les deux couches ensemble. La protection DDoS n’empêche pas un utilisateur légitime de surcharger votre service, et la limitation de l’application n’absorbe pas une attaque volumétrique.
Problèmes et considérations
Tenez compte des points suivants lorsque vous décidez comment implémenter ce modèle :
Prendre les décisions de limitation du débit le plus tôt possible. La limitation du débit est une décision architecturale qui a des répercussions sur l’ensemble du système. La rénovation ultérieure est coûteuse.
Alignez les limites de limitation avec le composant qui sature en premier.
Le taux de requêtes est la dimension la plus familière à limiter, mais le goulot d’étranglement réel est souvent des requêtes en cours simultanées, une profondeur de file d’attente, l’utilisation du processeur ou de la mémoire ou les limites propres d’une dépendance en aval. Une limite de requêtes par seconde ne protège pas un système dont le goulot d’étranglement se situe au niveau de la concurrence à un point de divergence.
À chaque point d’application de la limitation du débit, par exemple la passerelle, le service, une partition ou une dépendance en aval, identifiez ce qui sature en premier et fixez la limite sur ce paramètre. Pour une protection à concurrence limitée aux points de distribution, consultez le modèle Bulkhead, qui complète la limitation du débit.
Choisissez intentionnellement un algorithme de limitation. Adaptez-le à la tolérance du composant à protéger.
Algorithm Comportement et meilleure adéquation seau à jetons Prend en charge les rafales jusqu’à une taille configurée et applique un taux de remplissage stable. À utiliser pour les passerelles qui doivent absorber des pics de courte durée. Seau percé Émet à un taux constant. Utiliser pour les back-ends qui ont besoin d’un taux d’entrée stable. Fenêtre fixe Simple à implémenter, mais autorise des rafales consécutives aux limites de la fenêtre. Fenêtre glissante Atténue le problème aux limites entre fenêtres fixes, au prix d’une gestion d’état plus importante. Déterminez qui est affecté par la limite. Une limitation de débit appliquée à un périmètre large, tel qu’une passerelle régionale, peut affecter de nombreux utilisateurs sans lien entre eux, alors que seuls quelques-uns sont à l’origine de la charge.
Déterminez où réside le compteur lorsqu’une limite s’étend sur plusieurs nœuds. Les compteurs locaux sont rapides, mais sous-comptent lorsque le même client atteint plusieurs réplicas. Un compteur centralisé dans un magasin partagé comme Redis voit chaque requête, mais ajoute la latence à chaque décision. Pour estimer un taux global, divisez la limite entre les réplicas et rapprochez-les régulièrement.
Prenez rapidement des décisions de limitation du débit. Le système doit détecter une hausse de charge, réagir et revenir à la normale une fois la charge retombée. Ce processus nécessite une instrumentation continue des performances.
Perdre la charge de manière proactive, pas au bord de l’effondrement. Un mécanisme de limitation qui ne refuse qu’une fois qu’un composant est saturé fait grimper la latence avant que les clients ne subissent la contre-pression.
À mesure que l’utilisation approche de la limite difficile, commencez à rejeter une fraction croissante des requêtes. Le rejet précoce signale aux appelants de se retirer et empêche l’effondrement de la latence que les limites abruptes déclenchent souvent. Utilisez la latence p99 par rapport à votre SLO comme déclencheur principal. L’utilisation moyenne peut sembler correcte alors même que le p99 a déjà dépassé le seuil.
Lorsque vous pouvez distinguer la valeur des requêtes, abandonnez d’abord les tâches de moindre valeur ou celles qu’il est plus facile de réessayer. Pour plus d’informations, consultez le modèle File d’attente prioritaire.
Renvoyer un code d’état indiquant au client qu’un rejet temporaire est dû à une limitation du débit :
- HTTP 429 (trop de requêtes) : L’appelant dépasse un taux de requête configuré sur une fenêtre définie.
- HTTP 503 (Service indisponible) : Le service ne peut pas gérer la requête pour l’instant, souvent en raison d’un pic de charge inattendu.
Incluez un
Retry-Afteren-tête HTTP pour que le client puisse choisir une stratégie de nouvelle tentative. Retournez suffisamment de contexte pour que l’appelant réessaye délibérément au lieu de deviner. Par exemple, nommez la limite que l’appelant dépasse, clarifiez l’étendue affectée ou suggèrez un taux qui réussirait. Les rejet non expliqués n’aident pas les appelants à s’adapter.Propagez les signaux de surcharge provenant de vos dépendances au lieu de les absorber. Un service qui applique une limitation de débit à ses appelants doit également prendre en compte les réponses de limitation qu’il reçoit des services en aval dont il dépend. Si votre service masque une réponse 429 ou 503 en aval en réessayant silencieusement ou en renvoyant une réponse HTTP 500 générique (erreur interne du serveur), les appelants ne peuvent pas ralentir, les nouvelles tentatives s’amplifient et la surcharge se propage en cascade vers l’amont. L’anti-modèle Retry Storm décrit ce mode d’échec. Répercutez la contre-pression vers les appelants en amont afin que toute la chaîne d’appels réduise sa charge de concert.
Rendre le rejet moins cher que le travail qu’il empêche. Si le refus d’une demande nécessite une authentification intensive, une analyse approfondie ou une évaluation de stratégie complexe, une inondation de demandes rejetées peut encore saturer le système. Rejeter le plus tôt possible dans le pipeline de traitement des requêtes, et tester en charge le scénario de rejet lui aussi.
Prévoyez les cas où la limitation du débit ne peut pas faire gagner suffisamment de temps à la mise à l’échelle automatique. Si la demande augmente plus rapidement que les nouvelles capacités n’entrent en service, même un système bridé peut tomber en panne. Lorsque ce résultat est inacceptable, conservez des réserves de capacité plus importantes et configurez une mise à l’échelle automatique plus agressive.
N’utilisez pas la mise en cache en remplacement de la limitation du débit. Un cache réduit la charge moyenne sur l’origine, mais ne limite pas la charge maximale. Chaque défaut de cache est transmis au serveur d’origine, et lorsqu’une clé populaire expire en cas de trafic intense, de nombreuses requêtes peuvent se retrouver en concurrence pour la recharger. Utilisez la mise en cache pour réduire la charge normale et la limitation du débit pour borner le pire cas. Pour plus d’informations, consultez le modèle Cache-Aside.
Normalisez les coûts des ressources pour différentes opérations, car ils n’ont généralement pas de coûts d’exécution égaux. Par exemple, les limites de limitation du débit peuvent être plus élevées pour les opérations de lecture et plus faibles pour les opérations d’écriture. Ignorer le coût par opération peut épuiser la capacité et créer un vecteur d’attaque.
Permettre la modification de la configuration de limitation du débit à l’exécution. Lorsque la charge anormale arrive, vous devez ajuster les limites sans déploiement. Les déploiements sont lents et risqués pendant un incident. Le modèle de magasin de configuration externe externalise la configuration de façon à pouvoir la modifier en cours d’exécution.
Tenez compte des limites adaptatives au lieu des limites statiques. Certains SDK de limitation de débit réagissent aux signaux de latence ou de longueur de file d’attente afin que la limite s’adapte aux conditions réelles des composants. Associez toujours un limiteur adaptatif avec un maximum défini.
Revisitez vos limites à mesure que la charge de travail évolue. Les limiteurs adaptatifs ne peuvent pas suivre tous les types de dérives, tels que les modifications de SLO, les changements de capacité de dépendance ou les changements de coût par opération. Planifiez une révision périodique des opérateurs par rapport à ces entrées.
Quand utiliser ce modèle
Utilisez ce modèle :
Pour conserver un système au sein de ses SLO.
Pour empêcher un locataire unique de monopoliser les ressources d’application.
Pour gérer des augmentations de l’activité.
Pour limiter le niveau de ressource maximal dont un système a besoin.
Pour réduire le calcul à faible valeur pendant les périodes d’intensité carbone élevée du réseau.
Conception de la charge de travail
Évaluez comment utiliser le modèle de limitation lors de la conception d’une charge de travail afin de répondre aux objectifs et principes présentés 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. | Vous concevez les limites pour aider à prévenir l’épuisement des ressources qui pourrait conduire à des dysfonctionnements. Vous pouvez également utiliser ce modèle comme mécanisme de contrôle dans un plan de dégradation élégante. - RE :07 Autopréservation |
| Les décisions relatives à la conception de la sécurité permettent de garantir la confidentialité, l’intégrité et la disponibilité des données et des systèmes de votre charge de travail. | Vous pouvez concevoir les limites pour aider à prévenir l’épuisement des ressources qui pourrait résulter d’un abus automatisé du système. - Se :06 Contrôles de réseau - SE :08 Ressources de renforcement |
| L’optimisation des coûts se concentre sur le maintien et l’amélioration du retour sur investissement de votre charge de travail. | Les limites appliquées peuvent informer la modélisation des coûts et être directement liées au modèle métier de votre application. Elles mettent également en place des limites claires sur l’utilisation, qui peuvent être intégrées dans le dimensionnement des ressources. - CO:02 Modèle de coûts - 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. | Lorsque le système est sous forte demande, ce modèle aide à atténuer la congestion qui peut conduire à des goulots d’étranglement pour les performances. Vous pouvez également l’utiliser pour éviter proactivement les scénarios de voisin bruyant (effet « noisy neighbor »). - PE :02 Planification de la capacité - 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.
Example
Le schéma suivant montre la limitation du débit dans un système multilocataire.
Trois utilisateurs étiquetés sur la gauche représentent les locataires d’une application Surveys multilocataire : Adatum, Fabrikam et Contoso. Chaque utilisateur envoie des requêtes via un domaine personnalisé spécifique au locataire, que l’application utilise pour identifier le locataire. Adatum envoie 5 requêtes par seconde via surveys.adatum.com, Fabrikam envoie 10 requêtes par seconde via surveys.fabrikam.com, et Contoso envoie 150 requêtes par seconde via surveys.contoso.com. À droite, le rôle web d’application d’enquête mesure le taux de requête par seconde pour chaque locataire. Les flux de requêtes Adatum et Fabrikam sont transmis à l’application. Le flux de requête Contoso est bloqué par une erreur : réponse limitée, car le taux dépasse la limite par locataire.
Les utilisateurs de plusieurs organisations clientes accèdent à une application hébergée dans le cloud pour remplir et envoyer des enquêtes. L’application contient l’instrumentation qui surveille le taux auquel les utilisateurs de chaque locataire envoient des demandes.
Pour empêcher les utilisateurs d’un locataire de dégrader la réactivité et la disponibilité des utilisateurs d’autres locataires, l’application limite le taux de demandes par seconde que n’importe quel locataire unique peut envoyer. L’application bloque les requêtes qui dépassent cette limite.
Étape suivante
Ressources associées
- Mesurez la consommation de chaque locataire
- Mise à l’échelle automatique dans Azure
- Modèle de nivellement de charge basé sur une file d’attente
- Modèle file d’attente prioritaire
- Modèle de magasin de configuration externe