Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Att skapa tillförlitliga molnprogram kräver mer än att bara implementera funktioner. Det kräver också robusta strategier för felhantering. När du arbetar med distribuerade system och molntjänster måste ditt program vara redo att hantera felscenarier på ett korrekt sätt.
Azure SDK för Python innehåller en omfattande felmodell som är utformad för att hjälpa utvecklare att skapa motståndskraftiga program. Det är viktigt att förstå den här felmodellen för:
- Förbättra programmets tillförlitlighet genom att förutse och hantera vanliga felscenarier.
- Förbättra användarupplevelsen genom meningsfulla felmeddelanden och graciös försämring.
- Förenkla felsökningen genom att samla in och logga relevant diagnostikinformation.
Den här artikeln utforskar Azure SDK för Pythons felarkitektur och ger praktisk vägledning för att implementera effektiv felhantering i dina program.
Så här felar Azure SDK för Python-modeller
Azure SDK för Python använder en hierarkisk undantagsmodell som tillhandahåller allmänna och specifika funktioner för felhantering. Kärnan i den här modellen är AzureError, som fungerar som bas undantagsklass för alla fel relaterade till Azure SDK.
Undantagshierarki
AzureError
├── ClientAuthenticationError
├── ResourceNotFoundError
├── ResourceExistsError
├── ResourceModifiedError
├── ResourceNotModifiedError
├── ServiceRequestError
├── ServiceResponseError
└── HttpResponseError
Viktiga undantagstyper
| Error | Description |
|---|---|
AzureError |
Den grundläggande undantagsklassen för alla Azure SDK-fel. Använd det här undantaget som en catchall när du behöver hantera azure-relaterade fel. |
ClientAuthenticationError |
Utlöses när autentiseringen misslyckas. Vanliga orsaker är ogiltiga autentiseringsuppgifter, förfallna token och felkonfigurerade autentiseringsinställningar. |
ResourceNotFoundError |
Utlöses när du försöker komma åt en resurs som inte finns. Det här undantaget motsvarar vanligtvis HTTP 404-svar. |
ResourceExistsError |
Utlöses när du försöker skapa en resurs som redan finns. Det här undantaget hjälper till att förhindra oavsiktliga överskrivningar. |
ServiceRequestError |
Utlöses när SDK:t inte kan skicka en begäran till tjänsten. Vanliga orsaker är problem med nätverksanslutningar, problem med systemmatchning av domännamn och ogiltiga tjänstslutpunkter. |
ServiceResponseError |
Utlöses när tjänsten returnerar ett oväntat svar som SDK inte kan bearbeta. |
HttpResponseError |
Upphöjt för HTTP-felsvar (statuskoderna 4xx och 5xx). Det här undantaget ger åtkomst till den underliggande HTTP-svarsinformationen. |
Vanliga felscenarier
Genom att förstå vanliga felscenarier kan du implementera lämpliga hanteringsstrategier för varje situation.
Autentiserings- och auktoriseringsfel
Autentiseringsfel uppstår när SDK:t inte kan verifiera din identitet:
from azure.core.exceptions import ClientAuthenticationError
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
try:
credential = DefaultAzureCredential()
blob_service = BlobServiceClient(
account_url="https://myaccount.blob.core.windows.net",
credential=credential
)
# Attempt to list containers
containers = blob_service.list_containers()
except ClientAuthenticationError as e:
print(f"Authentication failed: {e.message}")
# Don't retry - fix credentials first
Auktoriseringsfel (vanligtvis HttpResponseError med 403 status) inträffar när du saknar behörighet:
from azure.core.exceptions import HttpResponseError
try:
blob_client.upload_blob(data)
except HttpResponseError as e:
if e.status_code == 403:
print("Access denied. Check your permissions.")
else:
raise
Resursfel
Hantera saknade resurser på ett korrekt sätt:
from azure.core.exceptions import ResourceNotFoundError
try:
blob_client = container_client.get_blob_client("myblob.txt")
content = blob_client.download_blob().readall()
except ResourceNotFoundError:
print("Blob not found. Using default content.")
content = b"default"
Förhindra att dubbletter av resurser skapas:
from azure.core.exceptions import ResourceExistsError
try:
container_client.create_container()
except ResourceExistsError:
print("Container already exists.")
# Continue with existing container
Serverfel
Hantera fel på serversidan på rätt sätt:
from azure.core.exceptions import HttpResponseError
try:
result = client.process_data(large_dataset)
except HttpResponseError as e:
if 500 <= e.status_code < 600:
print(f"Server error ({e.status_code}). The service may be temporarily unavailable.")
# Consider retry logic here
else:
raise
Metodtips för felhantering
Använd specifik undantagshantering: Fånga alltid specifika undantag innan du återgår till allmänna undantag:
from azure.core.exceptions import ( AzureError, ClientAuthenticationError, ResourceNotFoundError, HttpResponseError ) try: # Azure SDK operation result = client.get_resource() except ClientAuthenticationError: # Handle authentication issues print("Please check your credentials") except ResourceNotFoundError: # Handle missing resources print("Resource not found") except HttpResponseError as e: # Handle specific HTTP errors if e.status_code == 429: print("Rate limited. Please retry later.") else: print(f"HTTP error {e.status_code}: {e.message}") except AzureError as e: # Catch-all for other Azure errors print(f"Azure operation failed: {e}")Implementera lämpliga återförsöksstrategier: Vissa fel garanterar återförsök, medan andra inte gör det.
Försök inte igen:
- 401 Obehörig (autentiseringsfel)
- 403 Förbjudet (auktoriseringsfel)
- 400 Felaktig begäran (klientfel)
- 404 Hittades inte (om du inte förväntar dig att resursen ska visas)
Överväg att försöka igen:
- Tidsgräns för 408-begäran
- 429 För många begäranden (med lämplig backoff)
- 500 Internt serverfel
- 502 Felaktig gateway
- 503 Tjänsten är inte tillgänglig
- Tidsgräns för 504 Gateway
Extrahera meningsfull felinformation
from azure.core.exceptions import HttpResponseError try: client.perform_operation() except HttpResponseError as e: # Extract detailed error information print(f"Status code: {e.status_code}") print(f"Error message: {e.message}") print(f"Error code: {e.error.code if e.error else 'N/A'}") # Request ID is crucial for Azure support if hasattr(e, 'response') and e.response: request_id = e.response.headers.get('x-ms-request-id') print(f"Request ID: {request_id}")
Återförsöksprinciper och motståndskraft
Azure SDK innehåller inbyggda mekanismer för återförsök som hanterar tillfälliga fel automatiskt.
Standardbeteende för återförsök
De flesta Azure SDK-klienter innehåller standardprinciper för återförsök som:
- Försök igen vid anslutningsfel och specifika HTTP-statuskoder.
- Använd exponentiell backoff med jitter.
- Begränsa antalet återförsök.
Anpassa återförsöksprinciper
Om standardbeteendet inte passar ditt användningsfall kan du anpassa återförsöksprincipen:
from azure.storage.blob import BlobServiceClient
from azure.core.pipeline.policies import RetryPolicy
# Create a custom retry policy
retry_policy = RetryPolicy(
retry_total=5, # Maximum retry attempts
retry_backoff_factor=2, # Exponential backoff factor
retry_backoff_max=60, # Maximum backoff time in seconds
retry_on_status_codes=[408, 429, 500, 502, 503, 504]
)
# Apply to client
blob_service = BlobServiceClient(
account_url="https://myaccount.blob.core.windows.net",
credential=credential,
retry_policy=retry_policy
)
Undvik att hantera nätverks- och tidsgränsfel med anpassade loopar
Försök att använda inbyggda återförsök för nätverks- och tidsgränsfel innan du implementerar din egen anpassade logik.
from azure.core.exceptions import ServiceRequestError
import time
# Avoid this approach if possible
max_retries = 3
retry_count = 0
while retry_count < max_retries:
try:
response = client.get_secret("mysecret")
break
except ServiceRequestError as e:
retry_count += 1
if retry_count >= max_retries:
raise
print(f"Network error. Retrying... ({retry_count}/{max_retries})")
time.sleep(2 ** retry_count) # Exponential backoff
Implementera kretsbrytarmönster
För kritiska åtgärder bör du överväga att implementera kretsbrytarmönster:
class CircuitBreaker:
def __init__(self, failure_threshold=5, recovery_timeout=60):
self.failure_threshold = failure_threshold
self.recovery_timeout = recovery_timeout
self.failure_count = 0
self.last_failure_time = None
self.state = 'closed' # closed, open, half-open
def call(self, func, *args, **kwargs):
if self.state == 'open':
if time.time() - self.last_failure_time > self.recovery_timeout:
self.state = 'half-open'
else:
raise Exception("Circuit breaker is open")
try:
result = func(*args, **kwargs)
if self.state == 'half-open':
self.state = 'closed'
self.failure_count = 0
return result
except Exception as e:
self.failure_count += 1
self.last_failure_time = time.time()
if self.failure_count >= self.failure_threshold:
self.state = 'open'
raise e
Förstå felmeddelanden och koder
Azure-tjänster returnerar strukturerade felsvar som ger värdefull felsökningsinformation.
Analyserar felmeddelanden
from azure.core.exceptions import HttpResponseError import json try: client.create_resource(resource_data) except HttpResponseError as e: # Many Azure services return JSON error details if e.response and e.response.text(): try: error_detail = json.loads(e.response.text()) print(f"Error code: {error_detail.get('error', {}).get('code')}") print(f"Error message: {error_detail.get('error', {}).get('message')}") # Some services provide additional details if 'details' in error_detail.get('error', {}): for detail in error_detail['error']['details']: print(f" - {detail.get('code')}: {detail.get('message')}") except json.JSONDecodeError: print(f"Raw error: {e.response.text()}")Samla in diagnostikinformation: Samla alltid in viktig diagnostikinformation för felsökning.
import logging from azure.core.exceptions import AzureError logger = logging.getLogger(__name__) try: result = client.perform_operation() except AzureError as e: # Log comprehensive error information logger.error( "Azure operation failed", extra={ 'error_type': type(e).__name__, 'error_message': str(e), 'operation': 'perform_operation', 'timestamp': datetime.utcnow().isoformat(), 'request_id': getattr(e.response, 'headers', {}).get('x-ms-request-id') if hasattr(e, 'response') else None } ) raiseLoggning och diagnostik: Aktivera loggning på SDK-nivå för detaljerad felsökning:
import logging import sys # Configure logging for Azure SDKs logging.basicConfig(level=logging.DEBUG) # Enable HTTP request/response logging logging.getLogger('azure.core.pipeline.policies.http_logging_policy').setLevel(logging.DEBUG) # For specific services logging.getLogger('azure.storage.blob').setLevel(logging.DEBUG) logging.getLogger('azure.identity').setLevel(logging.DEBUG)Mer information om loggning finns i Konfigurera loggning i Azure-biblioteken för Python.
Använd nätverksspårning: För djup felsökning aktiverar du spårning på nätverksnivå:
Viktigt!
HTTP-loggning kan innehålla känslig information, till exempel kontonycklar i rubriker och andra autentiseringsuppgifter. Se till att skydda loggarna för att undvika att äventyra säkerheten.
from azure.storage.blob import BlobServiceClient # Enable network tracing blob_service = BlobServiceClient( account_url="https://myaccount.blob.core.windows.net", credential=credential, logging_enable=True, # Enable logging logging_body=True # Log request/response bodies (careful with sensitive data) )
Särskilda överväganden för asynkron programmering
När du använder asynkrona klienter kräver felhantering särskild uppmärksamhet.
Grundläggande asynkron felhantering
import asyncio from azure.core.exceptions import AzureError async def get_secret_async(client, secret_name): try: secret = await client.get_secret(secret_name) return secret.value except ResourceNotFoundError: print(f"Secret '{secret_name}' not found") return None except AzureError as e: print(f"Error retrieving secret: {e}") raiseHantera annulleringar
async def long_running_operation(client): try: result = await client.start_long_operation() # Wait for completion final_result = await result.result() return final_result except asyncio.CancelledError: print("Operation cancelled") # Cleanup if necessary if hasattr(result, 'cancel'): await result.cancel() raise except AzureError as e: print(f"Operation failed: {e}") raiseSamtidig felhantering
async def process_multiple_resources(client, resource_ids): tasks = [] for resource_id in resource_ids: task = client.get_resource(resource_id) tasks.append(task) results = [] errors = [] # Use gather with return_exceptions to handle partial failures outcomes = await asyncio.gather(*tasks, return_exceptions=True) for resource_id, outcome in zip(resource_ids, outcomes): if isinstance(outcome, Exception): errors.append((resource_id, outcome)) else: results.append(outcome) # Process successful results and errors appropriately if errors: print(f"Failed to process {len(errors)} resources") for resource_id, error in errors: print(f" - {resource_id}: {error}") return results
Sammanfattning av metodtips
Effektiv felhantering i Azure SDK för Python-program kräver att du:
- Förutse fel: Molnprogram måste förvänta sig och hantera partiella fel på ett korrekt sätt.
-
Använd specifik undantagshantering: Fånga specifika undantag som
ResourceNotFoundErrorochClientAuthenticationErrorinnan du återgår till allmänAzureErrorhantering. - Implementera logik för smart återförsök: Använd inbyggda återförsöksprinciper eller anpassa dem baserat på dina behov. Kom ihåg att inte alla fel ska utlösa återförsök.
- Samla in diagnostikinformation: Logga alltid begärande-ID,felkoder och tidsstämplar för effektiv felsökning.
- Ge meningsfull användarfeedback: Omvandla tekniska fel till användarvänliga meddelanden samtidigt som du bevarar teknisk information för support.
- Testfelscenarier: Inkludera felhantering i testtäckningen för att säkerställa att programmet fungerar korrekt under feltillstånd.
Relaterat innehåll
- Granska modulreferensen för Azure Core-undantag.
- Läs mer om felsökning av autentiserings- och auktoriseringsproblem.
- Utforska Azure Monitor OpenTelemetry för omfattande programövervakning.