A Pythonhoz készült Azure SDK által létrehozott hibák kezelése

A megbízható felhőalkalmazások létrehozásához nem csupán implementálási funkciókra van szükség. Emellett robusztus hibakezelési stratégiákat is igényel. Ha elosztott rendszerekkel és felhőszolgáltatásokkal dolgozik, az alkalmazásnak felkészültnek kell lennie a hibaforgatókönyvek megfelelő kezelésére.

A Pythonhoz készült Azure SDK átfogó hibamodellt biztosít, amely segít a fejlesztőknek rugalmas alkalmazások létrehozásában. Ennek a hibamodellnek a megértése elengedhetetlen a következő célokhoz:

  • Az alkalmazások megbízhatóságának javítása a gyakori meghibásodási forgatókönyvek előrejelzésével és kezelésével.
  • A felhasználói élmény javítása értelmes hibaüzenetek és kecses leromlás révén.
  • A hibaelhárítás egyszerűsítése a vonatkozó diagnosztikai információk rögzítésével és naplózásával.

Ez a cikk az Azure SDK for Python hibaarchitektúráját ismerteti, és gyakorlati útmutatást nyújt az alkalmazások hatékony hibakezelésének implementálásához.

Az Azure SDK for Python-modellek hibái

Az Azure SDK for Python egy hierarchikus kivételmodellt használ, amely általános és specifikus hibakezelési képességeket biztosít. Ennek a modellnek a lényege az AzureError, amely az Azure SDK-val kapcsolatos összes hiba alapkivételi osztályaként szolgál.

Kivételhierarchia

AzureError
├── ClientAuthenticationError
├── ResourceNotFoundError
├── ResourceExistsError
├── ResourceModifiedError
├── ResourceNotModifiedError
├── ServiceRequestError
├── ServiceResponseError
└── HttpResponseError

Fő kivételtípusok

Error Description
AzureError Az Azure SDK-hibák alapkivételi osztálya. Használja ezt a kivételt, ha kezelnie kell az Azure-ral kapcsolatos hibákat.
ClientAuthenticationError A hitelesítés sikertelenség esetén aktiválva. A gyakori okok közé tartoznak az érvénytelen hitelesítő adatok, a lejárt jogkivonatok és a helytelenül konfigurált hitelesítési beállítások.
ResourceNotFoundError Nem létező erőforrás elérésekor jelenik meg. Ez a kivétel általában a HTTP 404-válaszoknak felel meg.
ResourceExistsError Ez akkor merül fel, amikor már létező erőforrást próbál létrehozni. Ez a kivétel segít megelőzni a véletlen felülírásokat.
ServiceRequestError Akkor merül fel, ha az SDK nem tud kérést küldeni a szolgáltatásnak. A gyakori okok közé tartoznak a hálózati csatlakozási problémák, a tartománynévrendszer feloldási hibái és az érvénytelen szolgáltatásvégpontok.
ServiceResponseError Akkor merül fel, amikor a szolgáltatás váratlan választ ad vissza, amelyet az SDK nem tud feldolgozni.
HttpResponseError HTTP-hibaválaszokra (4xx és 5xx állapotkódok) emelve. Ez a kivétel hozzáférést biztosít a mögöttes HTTP-válasz részleteihez.

Gyakori hibaforgatókönyvek

A tipikus hibaforgatókönyvek megismerése segít az egyes helyzetek megfelelő kezelési stratégiáinak megvalósításában.

Hitelesítési és engedélyezési hibák

Hitelesítési hibák akkor fordulnak elő, ha az SDK nem tudja ellenőrizni az identitását:

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

Engedélyezési hibák (általában HttpResponseError az állapottal 403 ) akkor fordulnak elő, ha nem rendelkezik engedélyekkel:

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

Erőforráshibák

A hiányzó erőforrások kezelése kecsesen:

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"

Ismétlődő erőforrások létrehozásának megakadályozása:

from azure.core.exceptions import ResourceExistsError

try:
    container_client.create_container()
except ResourceExistsError:
    print("Container already exists.")
    # Continue with existing container

Kiszolgálóhibák

A kiszolgálóoldali hibák megfelelő kezelése:

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

Ajánlott eljárások a hibakezeléshez

  • Speciális kivételkezelés használata: Az általános kivételekre való visszalépés előtt mindig fogjon ki bizonyos kivételeket:

    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}")
    
  • Valósítsa meg a megfelelő újrapróbálkozési stratégiákat: Egyes hibák újrapróbálkozási kísérleteket tesznek szükségessé, míg mások nem.

    Ne próbálkozzon újra:

    • 401 Jogosulatlan (hitelesítési hibák)
    • 403 Tiltott (engedélyezési hibák)
    • 400 Hibás kérelem (ügyfélhibák)
    • 404 Nem található (hacsak nem számít az erőforrás megjelenésére)

    Fontolja meg az újrapróbálkozást:

    • 408 Kérelem időtúllépése
    • 429 Túl sok kérés (megfelelő visszalépéssel)
    • 500 belső kiszolgálóhiba
    • 502 Hibás átjáró
    • 503 Szolgáltatás nem érhető el
    • 504-átjáró időtúllépése
  • Hasznos hibainformációk kinyerés

    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}")
    

Újrapróbálkozás szabályzatai és rugalmassága

Az Azure SDK beépített újrapróbálkozási mechanizmusokat tartalmaz, amelyek automatikusan kezelik az átmeneti hibákat.

Az újrapróbálkozás alapértelmezett viselkedése

A legtöbb Azure SDK-ügyfél alapértelmezett újrapróbálkozási szabályzatokat tartalmaz, amelyek:

  • Próbálkozzon újra a kapcsolati hibákon és adott HTTP-állapotkódokon.
  • Exponenciális visszalépés használata jitterrel.
  • Az újrapróbálkozási kísérletek számának korlátozása.

Újrapróbálkozési szabályzatok testreszabása

Ha az alapértelmezett viselkedés nem felel meg a használati esetnek, testre szabhatja az újrapróbálkozési szabályzatot:

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
)

Ne kezelje a hálózati és időtúllépési hibákat egyéni hurkokkal

Mielőtt a saját egyéni logikáját alkalmazná, próbálja meg használni a beépített újrapróbálkozásokat a hálózati és időtúllépési hibák kezelésére.

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

Áramkör-megszakító minták implementálása

Kritikus műveletek esetén fontolja meg az áramkör-megszakító minták implementálását:

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

Hibaüzenetek és kódok ismertetése

Az Azure-szolgáltatások strukturált hibaválaszokat adnak vissza, amelyek értékes hibakeresési információkat nyújtanak.

  • Hibaválaszok elemzése

    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()}")
    
  • Diagnosztikai adatok rögzítése: A hibaelhárításhoz mindig rögzítse a legfontosabb diagnosztikai információkat:

    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
            }
        )
        raise
    
  • Naplózás és diagnosztika: Engedélyezze az SDK-szintű naplózást a részletes hibaelhárításhoz:

    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)
    

    A naplózással kapcsolatos további információkért lásd : Naplózás konfigurálása a Python Azure-kódtáraiban.

  • Hálózati nyomkövetés használata: A mély hibakereséshez engedélyezze a hálózati szintű nyomkövetést:

    Fontos

    A HTTP-naplózás tartalmazhat bizalmas információkat, például a fejlécekben lévő fiókkulcsokat és más hitelesítő adatokat. A biztonság veszélyeztetésének elkerülése érdekében mindenképpen védje ezeket a naplókat.

    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)
    )
    

Az aszinkron programozás speciális szempontjai

Az aszinkron ügyfelek használatakor a hibakezelés különös figyelmet igényel.

  • Alapszintű aszinkron hibakezelés

    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}")
            raise
    
  • Lemondások kezelése

    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}")
            raise
    
  • Egyidejű hibakezelés

    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
    

Az ajánlott eljárások összefoglalása

Az Azure SDK for Python-alkalmazások hatékony hibakezeléséhez a következő műveletekre van szükség:

  • Várható hibák: A felhőalkalmazásoknak kecsesen kell várniuk és kezelnie kell a részleges hibákat.
  • Speciális kivételkezelés használata: Fogjon ki bizonyos kivételeket, például ResourceNotFoundError és ClientAuthenticationError mielőtt visszatér az általános AzureError kezeléshez.
  • Intelligens újrapróbálkozásos logika implementálása: Használjon beépített újrapróbálkozési szabályzatokat, vagy szabja testre őket az igényeinek megfelelően. Ne feledje, hogy nem minden hiba aktiválja az újrapróbálkozásokat.
  • Diagnosztikai adatok rögzítése: A hatékony hibaelhárítás érdekében mindig naplózza a kérés azonosítóit, hibakódjait és időbélyegeit.
  • Adjon értelmes felhasználói visszajelzést: A technikai hibákat felhasználóbarát üzenetekké alakíthatja, miközben megőrzi a technikai részleteket a támogatás érdekében.
  • Tesztelési hibaforgatókönyvek: Adja meg a hibakezelést a tesztlefedettségben, hogy az alkalmazás hibafeltételek mellett megfelelően viselkedjen.