0Pricing
Serverless AWS Lambda Development · Leçon

Créer des systèmes sans serveur résilients

Concevez des architectures sans serveur hautement disponibles et tolérantes aux pannes en intégrant des modèles tels que les disjoncteurs, les nouvelles tentatives et l’idempotence dans vos fonctions.

Créer des systèmes sans serveur résilients est une leçon Serverless AWS Lambda Development gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Serverless AWS Lambda Development, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Serverless AWS Lambda Development comprend 4 leçons au total.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

Building Robust Serverless Systems

Welcome! In this lesson, we'll dive into designing highly resilient and fault-tolerant serverless applications. Even though AWS manages much of the infrastructure, your functions still need to handle failures gracefully.

We'll explore key architectural patterns to ensure your applications remain stable and performant, even when things go wrong.

The Reality of Distributed Systems

In a serverless world, your functions often interact with many other services: databases, APIs, message queues. These interactions happen over a network, and networks can be unreliable.

  • Transient Failures: Brief network glitches or service slowdowns.
  • Downstream Service Issues: A service your Lambda calls might be temporarily unavailable.
  • Unexpected Data: Malformed input can cause your function to crash.

Designing for these "failures" is crucial for a stable system.

Lambda's Built-in Retry Logic

For certain invocation types, AWS Lambda automatically retries your function if it fails. This is a powerful built-in resilience mechanism for asynchronous invocations.

For example, if an SQS queue triggers your Lambda and your function errors, Lambda (or SQS) will retry the invocation a few times. This helps overcome transient issues without any code changes.

However, retries aren't a silver bullet; they can lead to duplicate processing if not handled carefully.

Making Operations Idempotent

When retries happen, your function might execute the same operation multiple times. This is where idempotency comes in.

An idempotent operation is one that can be applied multiple times without changing the result beyond the initial application.

  • Example: Setting a value (x = 5) is idempotent.
  • Non-Example: Incrementing a value (x++) is NOT idempotent, as each retry would change the value.

For resilient systems, many operations should strive to be idempotent.

Keys to Idempotent Functions

To make your Lambda functions idempotent, you often need to track the state of a request. This typically involves:

  1. Generating a unique Idempotency Key for each request (e.g., from request ID, event source ID).
  2. Checking if this key has already been processed before performing the core logic.
  3. Storing the result or status of the operation associated with the key.

This ensures that even if a function is retried, the core side-effect only occurs once.

import hashlib
import json

# Imagine a database or cache for storing processed requests
# For simplicity, using a global dict here. A real app uses persistent storage.
processed_requests = {}

def is_idempotent(event_payload):
    # Create a unique key from the event payload
    # For a real app, use a proper hashing/unique ID strategy
    event_hash = hashlib.md5(json.dumps(event_payload, sort_keys=True).encode('utf-8')).hexdigest()

    if event_hash in processed_requests:
        print(f"Request with hash {event_hash} already processed.")
        return True
    
    processed_requests[event_hash] = "processing" # Mark as processing
    return False

def lambda_handler(event, context):
    if is_idempotent(event):
        return {
            'statusCode': 200,
            'body': json.dumps('Request already processed or is being processed.')
        }

    # Simulate actual work (e.g., writing to a database)
    print(f"Processing new request: {event}")
    
    # In a real scenario, update processed_requests[event_hash] = "completed"
    # after successful processing and store the result in persistent storage.
    
    return {
        'statusCode': 200,
        'body': json.dumps('Request processed successfully!')
    }

Preventing Cascading Failures

The Circuit Breaker pattern is a powerful way to prevent a failing service from causing cascading failures throughout your application.

Imagine a call to an external API that starts failing. Continuously retrying it will just waste resources and slow down your function. A circuit breaker detects this and "opens" the circuit, stopping calls to the failing service temporarily.

This gives the failing service time to recover and prevents your application from getting bogged down.

How a Circuit Breaker Works

A circuit breaker typically has three states:

  • Closed: Operations proceed as normal. If failures exceed a threshold, it transitions to Open.
  • Open: All calls to the protected service immediately fail (or return a fallback). After a timeout, it transitions to Half-Open.
  • Half-Open: A limited number of test calls are allowed through. If these succeed, it transitions back to Closed. If they fail, it returns to Open.

This intelligent behavior allows for self-healing.

Implementing a Simple Circuit Breaker

Implementing a full circuit breaker involves managing state (failures, success counts, last failure time). For serverless, this state might be stored in a shared cache (like ElastiCache) or a database.

While complex to implement from scratch in a simple Lambda, understanding the logic is key. Libraries exist for various languages to help, or you can leverage AWS services like Step Functions to orchestrate retry logic with delays.

import time

class CircuitBreaker:
    def __init__(self, failure_threshold=3, reset_timeout=5):
        self.state = "CLOSED"
        self.failure_count = 0
        self.last_failure_time = 0
        self.failure_threshold = failure_threshold
        self.reset_timeout = reset_timeout # seconds

    def call(self, func, *args, **kwargs):
        if self.state == "OPEN":
            if time.time() - self.last_failure_time > self.reset_timeout:
                self.state = "HALF-OPEN"
                # In a real app, log this state change
            else:
                raise Exception("Circuit is open, service unavailable.")
        
        try:
            result = func(*args, **kwargs)
            if self.state == "HALF-OPEN":
                self.state = "CLOSED"
                self.failure_count = 0
                # In a real app, log this state change
            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"
                # In a real app, log this state change
            raise e

Timeouts Prevent Hanging

Another crucial resilience pattern is using timeouts for external calls. If your Lambda function calls another service (e.g., a database, an HTTP API), that call could hang indefinitely if the service is unresponsive.

Configuring a timeout ensures your function doesn't wait forever, freeing up resources and allowing for retry logic to kick in faster. AWS Lambda itself has a configurable timeout, but you should also set timeouts within your code for specific external requests.

Resilient Design Challenge

Consider a Lambda function that processes incoming orders. If the function fails after successfully deducting payment but before updating the order status in a database, and then retries, what problem could arise if the payment deduction is NOT idempotent?

Summary: Building for Failure

We've covered essential patterns for building resilient serverless applications:

  • Retries: Lambda's built-in mechanism for transient errors.
  • Idempotency: Ensuring operations can be safely retried without unintended side-effects (e.g., duplicate charges).
  • Circuit Breakers: Preventing cascading failures by intelligently stopping calls to failing services.
  • Timeouts: Protecting against unresponsive external services.

By applying these principles, you can create serverless systems that gracefully handle inevitable failures.

Questions Fréquemment Posées

La leçon « Créer des systèmes sans serveur résilients » est-elle gratuite ?

Oui — le texte complet de « Créer des systèmes sans serveur résilients » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Serverless AWS Lambda Development, passe à CoddyKit PRO. Le cours Serverless AWS Lambda Development comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Créer des systèmes sans serveur résilients » ?

Concevez des architectures sans serveur hautement disponibles et tolérantes aux pannes en intégrant des modèles tels que les disjoncteurs, les nouvelles tentatives et l’idempotence dans vos fonctions. Tu pratiques Serverless AWS Lambda Development avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Serverless AWS Lambda Development ?

Aucune expérience préalable n'est requise. Serverless AWS Lambda Development sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Créer des systèmes sans serveur résilients » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Serverless AWS Lambda Development ?

Oui. Chaque leçon Serverless AWS Lambda Development inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Déploiements Canary et Blue/Green
  2. Créer des systèmes sans serveur résilients
  3. Modèles d’architecture sans serveur
  4. Optimisation des coûts dans les architectures sans serveur
← Retour à Serverless AWS Lambda Development