Comprendre le pipeline HTTP et les nouvelles tentatives dans le Kit de développement logiciel (SDK) Azure pour Python

Lorsque vous effectuez un appel à n’importe quel service Azure à l’aide du Kit de développement logiciel (SDK) Azure pour Python, votre demande ne passe pas directement au service Azure. Il n’est pas important de savoir s’il s’agit du Stockage Blob Azure, d’Azure Key Vault, d’Azure Cosmos DB ou d’un autre service HTTP. Au lieu de cela, votre requête transite par un pipeline HTTP sophistiqué qui gère automatiquement les préoccupations transversales critiques.

Comprendre le fonctionnement du pipeline HTTP est essentiel pour créer des applications robustes et performantes. Pipeline :

  • Gère les réessais pour les pannes transitoires.
  • Gère l’authentification.
  • Fournit des fonctionnalités de journalisation.
  • Vous permet d’ajouter un comportement personnalisé si nécessaire.

Cette connaissance vous aide à déboguer les problèmes de performances, à optimiser la résilience et à personnaliser l’interaction de votre application avec les services Azure.

Qu’est-ce que le pipeline HTTP ?

Le Kit de développement logiciel (SDK) Azure pour Python utilise une architecture de pipeline HTTP interne pour traiter toutes les requêtes et réponses. Ce pipeline se compose d’une série de stratégies qui s’exécutent en séquence. Chaque stratégie est responsable d’un aspect spécifique de la communication HTTP. Considérez le pipeline comme une chaîne d’étapes de traitement :

Client Request → Retry Policy → Authentication Policy → Logging Policy → HTTP Transport → Azure Service
                                                                                              ↓
Client Response ← Retry Policy ← Authentication Policy ← Logging Policy ← HTTP Transport ← Response

Chaque stratégie du pipeline peut :

  • Modifiez la demande avant son envoi.
  • Traitez la réponse une fois qu’elle a été reçue.
  • Effectuez des actions telles que réessayer les requêtes échouées.
  • Ajoutez des en-têtes, des informations de journal ou implémentez une logique personnalisée.

Stratégies clés dans le pipeline

Le Kit de développement logiciel (SDK) Azure pour Python inclut plusieurs stratégies intégrées qui gèrent des scénarios courants :

  • RetryPolicy: réessaye automatiquement les demandes qui échouent en raison d’erreurs temporaires. Cette stratégie implémente une logique de nouvelle tentative intelligente avec interruption exponentielle pour éviter les interruptions de service.
  • BearerTokenCredentialPolicy: gère l’authentification en acquérant et en actualisant automatiquement les jetons d’accès. Cette stratégie garantit que vos demandes incluent des informations d’identification d’authentification valides sans gestion manuelle des jetons.
  • NetworkTraceLoggingPolicy: capture des informations détaillées sur les requêtes et réponses HTTP à des fins de débogage. Cette stratégie est inestimable lorsque vous résolvez les problèmes de communication.
  • HttpTransport: couche la plus basse du pipeline qui envoie réellement des requêtes HTTP sur le réseau. Dans le Kit de développement logiciel (SDK) Azure pour Python, cette stratégie est généralement implémentée à l’aide de requêtes ou d’aiohttps pour les opérations asynchrones.

Autres stratégies

  • RedirectPolicy: gère automatiquement les redirections HTTP.
  • DistributedTracingPolicy: s’intègre aux systèmes de suivi distribués pour la surveillance.
  • ProxyPolicy: route les requêtes via des proxys HTTP lorsqu’elles sont configurées.
  • UserAgentPolicy : ajoute des informations de version du SDK aux en-têtes de requête.

Comportement de nouvelle tentative

Le Kit de développement logiciel (SDK) Azure pour Python implémente une logique de nouvelle tentative intelligente pour gérer automatiquement les défaillances temporaires. Comprendre ce comportement vous aide à créer des applications plus résilientes.

Conditions retentées automatiquement

Le Kit de développement logiciel (SDK) réessaye de demander ces codes d’état HTTP :

  • 408 Délai d’expiration de la demande : le serveur a expiré en attente de la demande.
  • 429 Trop de demandes : la limitation du débit est en vigueur.
  • Erreur de serveur interne 500 : problème de serveur temporaire.
  • Passerelle incorrecte 502 : problème réseau temporaire.
  • 503 Service indisponible : Service temporairement indisponible.
  • Délai d’expiration de la passerelle 504 : délai d’expiration de la passerelle ou du proxy.

Configuration de nouvelle tentative par défaut

Les paramètres de nouvelle tentative par défaut fournissent un bon équilibre entre la résilience et les performances :

  • Nombre maximal de tentatives de réessai : 3
  • Mode de réessai : Backoff exponentiel
  • Délai de base : 0,8 secondes
  • Délai maximal : 60 secondes
  • Durée maximale de nouvelle tentative : 120 secondes

Le calcul d’interruption exponentielle suit ce modèle :

delay = min(base_delay * (2 ** retry_attempt), max_delay)

Personnaliser les réessais

Vous pouvez personnaliser le comportement de nouvelle tentative lorsque vous créez des clients sdk pour qu’ils correspondent aux exigences spécifiques de votre application.

from azure.storage.blob import BlobServiceClient
from azure.core.pipeline.policies import RetryPolicy

# Custom retry configuration
retry_policy = RetryPolicy(
    retry_total=5,                    # Maximum number of retry attempts
    retry_backoff_factor=0.5,         # Base backoff time in seconds
    retry_backoff_max=120,            # Maximum backoff time in seconds
    retry_on_status_codes=[429, 500, 502, 503, 504]  # HTTP status codes to retry
)

# Apply custom retry policy to client
client = BlobServiceClient(
    account_url="https://myaccount.blob.core.windows.net",
    credential=credential,
    retry_policy=retry_policy
)

Désactiver les réessais

Pour les scénarios où les nouvelles tentatives ne sont pas appropriées :

from azure.core.pipeline.policies import RetryPolicy

# Disable retries completely
no_retry_policy = RetryPolicy(retry_total=0)

client = BlobServiceClient(
    account_url="https://myaccount.blob.core.windows.net",
    credential=credential,
    retry_policy=no_retry_policy
)

Diagnostiquer et déboguer le comportement de nouvelle tentative

Comprendre quand et pourquoi les nouvelles tentatives se produisent est essentielle pour résoudre les problèmes de performances.

Activer la journalisation du Kit de développement logiciel (SDK

Le Kit de développement logiciel (SDK) Azure pour Python utilise l’infrastructure de journalisation standard de Python :

import logging
import sys

# Configure logging to see retry attempts
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    stream=sys.stdout
)

# Enable specific Azure SDK loggers
azure_logger = logging.getLogger('azure')
azure_logger.setLevel(logging.DEBUG)

# Now SDK operations will log retry attempts

Identifier les modèles de nouvelle tentative

Recherchez les entrées de journal telles que :

Retry attempt 1 for request [GET] https://myaccount.blob.core.windows.net/container/blob
Waiting 0.8 seconds before retry

Pièges de nouvelle tentative courants

  • Nouvelles tentatives d’erreurs non temporaires : Le Kit de développement logiciel (SDK) n’effectue pas de nouvelles tentatives d’erreurs client (4xx), à l’exception de 408 et 429.
  • Ignorer la latence des nouvelles tentatives : N’oubliez pas que les nouvelles tentatives ajoutent une latence aux opérations ayant échoué.
  • Fournir un délai d’attente insuffisant : Assurez-vous que le délai d’expiration total de votre opération prend en compte les retards dus aux nouvelles tentatives.

Avancé : Ajouter des stratégies personnalisées

Vous pouvez étendre le pipeline avec des stratégies personnalisées pour des scénarios spécialisés.

Créer une stratégie personnalisée

from azure.core.pipeline import PipelineRequest, PipelineResponse
from azure.core.pipeline.policies import HTTPPolicy
from typing import Any, Optional

class CustomTelemetryPolicy(HTTPPolicy):
    """Custom policy to add telemetry headers"""
    
    def send(self, request: PipelineRequest) -> PipelineResponse:
        # Add custom header before sending request
        request.http_request.headers['X-Custom-Telemetry'] = 'my-app-v1.0'
        
        # Continue with the pipeline
        response = self.next.send(request)
        
        # Log response time
        print(f"Request to {request.http_request.url} completed")
        
        return response

Appliquer des stratégies personnalisées

from azure.storage.blob import BlobServiceClient

# Create client with custom policy
client = BlobServiceClient(
    account_url="https://myaccount.blob.core.windows.net",
    credential=credential,
    per_call_policies=[CustomTelemetryPolicy()],  # Policies that run per request
    per_retry_policies=[]  # Policies that run per retry attempt
)

Ordre des stratégies

Les stratégies s’exécutent dans un ordre spécifique :

  • Stratégies par appel (exécuter une fois par opération).
  • Politique de réessai.
  • Stratégies par nouvelle tentative (exécuter sur chaque tentative).
  • Stratégie d’authentification.
  • Transport HTTP.

Meilleures pratiques

Utiliser les paramètres par défaut lorsque cela est possible

La configuration de nouvelle tentative par défaut fonctionne bien pour la plupart des scénarios. Personnalisez uniquement lorsque vous avez des exigences spécifiques.

Instructions de personnalisation

Lorsque vous personnalisez le comportement de nouvelle tentative :

  • Utilisez le repli exponentiel : Utilisé pour éviter de submerger les services lors de la récupération.
  • Définir des limites raisonnables : Limitez le temps de nouvelle tentative total pour empêcher l’attente indéfinie.
  • Surveiller les métriques de nouvelle tentative : Suivez les taux de nouvelles tentatives en production pour identifier les problèmes.
  • Envisagez les disjoncteurs : Implémentez des modèles disjoncteur pour les scénarios à volume élevé.

Qu’est-ce qu’il ne faut pas réessayer

Évitez de réessayer ces types d’erreurs :

  • Échecs d’authentification (401, 403) : Les erreurs d’authentification nécessitent de corriger les informations d’identification, et non de réessayer.
  • Erreurs du client (400, 404) : Les erreurs du client indiquent des problèmes avec la requête elle-même.
  • Erreurs de logique métier : Erreurs spécifiques à l’application qui ne sont pas résolues avec des nouvelles tentatives.

Excellence opérationnelle

  • IDs de corrélation des journaux : Inclure x-ms-client-request-id dans les journaux pour la prise en charge d’Azure.
  • Définissez les délais d’expiration appropriés : Équilibre entre la fiabilité et l’expérience utilisateur.
  • Comportement de nouvelle tentative de test : Vérifiez que votre application gère correctement les nouvelles tentatives.
  • Surveiller les performances : Suivez les latences P95/P99 (métriques de latence basées sur centile), y compris la surcharge de nouvelle tentative.