Istio open source propose un disjoncteur uniquement au niveau du service : toutes les routes vers un service partagent la même politique et les règles ne s'appliquent qu'après le routage. Si une API échoue, le disjoncteur impacte l'ensemble des routes vers ce service.
Service Mesh (ASM) étend Istio avec un disjoncteur au niveau des routes. Le filtre com.aliyun.break filter évalue les règles de disjonction par route avant que le trafic n'atteigne le service en amont. Une API défaillante déclenche le disjoncteur uniquement pour sa propre route, tandis que les autres routes continuent de traiter les requêtes normalement.
Fonctionnement du disjoncteur au niveau des routes
Le disjoncteur standard d'Istio utilise deux paramètres dans le champ trafficPolicy d'une règle de destination :
**
ConnectionPoolSettings** : limite le nombre maximal de connexions, de requêtes en attente et de requêtes par connexion vers un service. Les requêtes excédentaires sont mises en file d'attente, expirent ou font l'objet de nouvelles tentatives.**
OutlierDetection** : analyse périodiquement les hôtes en amont et exclut ceux qui sont défectueux du pool d'équilibrage de charge en fonction des erreurs consécutives.
L'exemple suivant présente une règle de destination Istio standard avec les paramètres de disjonction. Pour plus d'informations, consultez la documentation Règle de destination.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
Cette approche présente deux limites :
Le disjoncteur s'applique au niveau du service, et non à des API ou des routes individuelles.
Le disjoncteur ne prend effet qu'après le routage.
ASM surmonte ces deux limites grâce à la définition de ressource personnalisée (CRD) ASMCircuitBreaker. Sur le plan de données, ASM étend la chaîne de filtres Envoy avec le filtre com.aliyun.break filter afin d'évaluer les règles de disjonction avant que la requête ne soit routée vers le service en amont. Sur le plan de contrôle, la CRD ASMCircuitBreaker offre une interface déclarative, ce qui évite de gérer directement la configuration Envoy sous-jacente.
Le disjoncteur au niveau des routes prend en charge les protocoles HTTP et gRPC.
Prérequis
Avant de commencer, assurez-vous d'avoir :
Une instance ASM Édition Enterprise ou Édition Ultimate, version V1.13.4 ou ultérieure. Consultez la rubrique Créer une instance ASM
Un cluster ajouté à l'instance ASM. Consultez la rubrique Ajouter un cluster à une instance ASM
Une passerelle d'entrée déployée dans l'instance ASM. Consultez la rubrique Créer une passerelle d'entrée
Les services Bookinfo et HTTPBin déployés. Consultez la rubrique Déployer une application dans une instance ASM
kubectl connecté à l'instance ASM. Consultez la rubrique Utiliser kubectl sur le plan de contrôle pour accéder aux ressources Istio
Une passerelle Istio et un service virtuel configurés. Consultez les rubriques Gérer les passerelles Istio et Gérer les services virtuels
L'outil de test de charge hey installé
Les fichiers de configuration pour ce tutoriel téléchargés
Présentation du scénario
Ce tutoriel illustre le disjoncteur au niveau des routes avec deux services situés derrière la même passerelle d'entrée :
Bookinfo (namespace
default) : dessert la route/productpageHTTPBin (namespace
foo) : dessert la route/httpbin
Une règle de disjonction cible uniquement httpbin-route-name1. Lorsqu'HTTPBin déclenche le disjoncteur, les requêtes vers /httpbin reçoivent une réponse d'erreur personnalisée. Les requêtes vers /productpage continuent de fonctionner normalement, ce qui prouve que le disjoncteur au niveau des routes isole les pannes sur des routes individuelles.

Référence des champs ASMCircuitBreaker
La CRD ASMCircuitBreaker définit les règles de disjonction par route. L'exemple suivant cible la route nginx-route-name1 sur l'hôte virtuel bf2.example.com:80 :
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMCircuitBreaker
metadata:
name: ingressgateway
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
isGateway: true
configs:
- match:
vhost:
name: "bf2.example.com"
port: 80
route:
name_match: nginx-route-name1
breaker_config:
slow_request_rt: 0.1s
break_duration: 90s
window_size: 10s
max_slow_requests: 10
min_request_amount: 3
error_percent:
value: 60
custom_response:
header_to_add:
x-envoy-circuitbreak: "true"
body: "hello, break!"
status_code: 499
| Champ | Description | Exemple de valeur | Conseils de réglage |
|---|---|---|---|
isGateway |
Applique la règle à une passerelle lorsque la valeur est définie sur true. Définissez la valeur sur false pour l'appliquer à un proxy sidecar. Valeur par défaut : false. |
true |
Définissez la valeur sur true pour les règles de passerelle d'entrée. |
slow_request_rt |
Seuil de temps de réponse. Les requêtes dépassant cette durée sont comptabilisées comme lentes. | 0.1s |
Des valeurs plus basses identifient davantage de requêtes comme lentes. Commencez par votre latence P99 et ajustez. |
max_slow_requests |
Nombre maximal de requêtes lentes autorisées par fenêtre de détection. Le disjoncteur se déclenche lorsque ce seuil est dépassé. | 10 |
Définissez une valeur plus basse pour une protection plus stricte, au prix d'un déclenchement plus fréquent du disjoncteur. Définissez une valeur plus élevée pour tolérer des pics occasionnels. |
error_percent.value |
Taux d'erreur maximal (%). Le disjoncteur se déclenche lorsque le taux d'erreur dépasse cette valeur et que le nombre total de requêtes atteint min_request_amount. |
60 |
Des valeurs plus basses déclenchent le disjoncteur plus tôt. Plage courante : 50–80 %. |
min_request_amount |
Nombre minimal de requêtes requis avant que le disjoncteur ne puisse se déclencher. Évite les faux positifs lors d'un faible trafic. | 3 |
Définissez une valeur plus élevée dans les environnements à faible trafic pour éviter les faux positifs. |
window_size |
Durée de la fenêtre glissante pour le comptage des requêtes lentes et des erreurs. | 10s |
Des fenêtres plus courtes réagissent plus vite mais sont plus sensibles aux rafales. Des fenêtres plus longues lissent le bruit. |
break_duration |
Durée pendant laquelle le disjoncteur reste actif. Toutes les requêtes correspondantes reçoivent la réponse personnalisée durant cette période. À l'expiration de cette durée, le circuit se réinitialise et les requêtes sont à nouveau autorisées. | 90s |
Définissez la valeur en fonction du temps de récupération attendu du service en amont. |
custom_response |
Réponse HTTP renvoyée lorsque le disjoncteur est actif. Prend en charge status_code, body et header_to_add. |
Voir le fichier YAML ci-dessus | Utilisez un code d'état et un en-tête distinctifs afin que les clients et la supervision puissent distinguer les réponses de disjonction des erreurs réelles du service en amont. |
Pour tous les champs disponibles, consultez la rubrique Description des champs ASMCircuitBreaker.
Configurer et vérifier une règle de disjonction
Créez une règle de disjonction pour la route httpbin-route-name1 sur l'hôte virtuel bf2.example.com:80, puis vérifiez qu'elle se déclenche correctement et n'affecte que la route ciblée.
Étape 1 : Créer la ressource ASMCircuitBreaker
Enregistrez le fichier YAML suivant sous le nom asmcircuitbreaker-test-gw.yaml :
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMCircuitBreaker
metadata:
name: ingressgateway
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
isGateway: true
configs:
- match:
vhost:
name: "bf2.example.com"
port: 80
route:
name_match: httpbin-route-name1
breaker_config:
slow_request_rt: 0.1s
break_duration: 90s
window_size: 10s
max_slow_requests: 10
min_request_amount: 3
error_percent:
value: 60
custom_response:
header_to_add:
x-envoy-overload: "true"
body: "hello, break!"
status_code: 499
Appliquez la ressource :
kubectl apply -f asmcircuitbreaker-test-gw.yaml
Cette règle surveille la route httpbin-route-name1 sur une fenêtre glissante de 10 secondes. Le disjoncteur se déclenche lorsque l'une des conditions suivantes est remplie :
Plus de 10 requêtes lentes (temps de réponse > 0,1 seconde)
Le taux d'erreur dépasse 60 %, avec au moins 3 requêtes au total
Une fois déclenché, toutes les requêtes vers /httpbin reçoivent une réponse 499 avec le corps hello, break! pendant 90 secondes. À l'expiration de la durée break_duration de 90 secondes, le circuit se réinitialise et les requêtes sont à nouveau transmises à HTTPBin.
Étape 2 : Déclencher le disjoncteur avec des échecs simulés
Utilisez curl pour générer des requêtes lentes ou des réponses d'erreur. Les premières requêtes aboutissent normalement car les seuils n'ont pas encore été atteints.
Simuler un délai d'une seconde (dépasse le seuil slow_request_rt de 0,1 seconde) :
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/httpbin/delay/1 -v
Simuler une erreur 500 :
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/httpbin/status/500 -v
Répétez l'une ou l'autre commande au moins 10 fois en 10 secondes. Au fur et à mesure que les compteurs s'accumulent dans la fenêtre glissante, vous observez la progression suivante :
Requêtes initiales : les premières requêtes aboutissent normalement (HTTP 200 depuis HTTPBin ou la réponse de délai/erreur attendue depuis HTTPBin lui-même). Le disjoncteur ne s'est pas déclenché car les seuils n'ont pas été atteints.
-
Seuil franchi : après que suffisamment de requêtes ont dépassé les seuils configurés dans la fenêtre de 10 secondes, les requêtes suivantes renvoient la réponse personnalisée de disjonction :
< HTTP/1.1 499 Unknown < Content-Length: 12 < Content-Type: text/plain < x-envoy-overload: true < Date: Thu, 13 Jan 2022 03:03:09 GMT < Server: istio-envoy < Hello,Break!
Trois indicateurs confirment que le disjoncteur est actif :
Code d'état :
499(lestatus_codepersonnalisé défini dans la règle)En-tête :
x-envoy-overload: true(l'en-tête personnalisé issu deheader_to_add)Corps :
Hello,Break!(lebodypersonnalisé)
Étape 3 : Vérifier que les autres routes ne sont pas affectées
Pendant que le disjoncteur est actif pour /httpbin, envoyez une requête à la route Bookinfo /productpage :
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/productpage -v
Une réponse HTTP 200 réussie confirme que la règle de disjonction n'affecte que la route httpbin-route-name1. Bookinfo continue de servir les requêtes normalement car la règle cible une route spécifique, et non l'ensemble du service.