Dans le développement d'applications modernes, les architectures sans serveur sont passées d'une expérience de niche à un choix général pour construire des systèmes évolutifs et rentables. La promesse de gestion zéro infrastructure, d'échelle automatique et de tarification par exercice fait appel aux startups et aux entreprises. Cependant, la réalisation de la latence élevée et de la sous-capacité de 100 millisecondes dans un cadre sans serveur exige dès le départ une conception soignée. Sans optimisation délibérée, les fonctions sans serveur peuvent souffrir de démarrages froids, de throttling et de performances imprévisibles sous charge.

Comprendre l'architecture sans serveur

L'informatique sans serveur, sous sa forme la plus courante, fait référence aux plateformes Fonctions-as-a-Service (FaaS) telles que AWS Lambda, Azure Functions et Google Cloud Functions. Les développeurs écrivent des fonctions apatrides qui sont déclenchées par des événements — requêtes HTTP, changements de base de données, messages de file d'attente ou timers programmés — et le fournisseur de cloud gère toutes les prestations, l'échelle et le patching des serveurs.

Au-delà de FaaS, sans serveur, il englobe également des services gérés comme AWS DynamoDB, Aurora Serverless, Amazon API Gateway, CloudFront et SQS. Une véritable application sans serveur tisse ces services en un tissu axé sur l'événement. Les principaux avantages sont l'échelle automatique, la facturation granulaire (vous payez seulement pour le temps de calcul consommé) et le temps plus rapide pour le marché.

Pour les charges de travail à forte intensité de débit, les plateformes sans serveur peuvent atteindre des milliers d'exécutions simultanées presque instantanément. La latence, cependant, est plus nuancée. Cold starts — le délai lorsqu'une nouvelle instance de fonction est initialisée — peut ajouter des centaines de millisecondes à la première requête.

Principales mesures de rendement et compromis

Pour concevoir des mesures à haut débit et à faible latence, il faut définir des paramètres clairs et comprendre les compromis inhérents :

  • Groughput – le nombre de demandes ou d'événements que le système peut traiter par seconde. Ceci est limité par les limites de cohérence de fonction (soft et hard), les quotas de service en aval (p. ex., la capacité de la table DynamoDB) et la bande passante du réseau.
  • Latence – le temps entre l'initiation de la demande et la livraison de la réponse. Les démarrages à froid, les sauts en réseau, les requêtes de base de données et la sérialisation/désérialisation contribuent tous.
  • Coût – le prix sans serveur est basé sur le temps d'exécution (GB‐secondes), le nombre d'invocations et le transfert de données.
  • Consistance vs performance – des bases de données fortement cohérentes (p. ex. DynamoDB en mode de lecture cohérente) ajoutent de la latence. Finalement, des systèmes cohérents (p. ex. DynamoDB lit éventuellement, caches de bord CloudFront) améliorent la performance de lecture au prix de l'impasse.

Par exemple, un système d'appel d'offres en temps réel peut prioriser la latence de sous‐10 ms et sacrifier un certain débit en utilisant la concordance fournie, tandis qu'un pipeline de traitement par lots peut favoriser un débit élevé et tolérer des secondes de latence. Comprendre les objectifs spécifiques de niveau de service (ALS) de votre demande est la première étape.

Principes clés pour les latences élevées et faibles

Les principes suivants constituent le fondement des applications sans serveur à haute performance:

Utilisation efficace des ressources

L'échelle automatique est inhérente à l'absence de serveur, mais pas à l'instantané. AWS Lambda, par exemple, commence à effectuer des rafales de 500 exécutions simultanées par minute pour chaque fonction (sous réserve de la limite de concurrence de cassure de cassure). Pour les pics de trafic qui dépassent ce taux, les requêtes sont tronquées par une erreur 429. Pour atténuer, vous pouvez demander un quota d'éclatement plus élevé, des fonctions préchauffées avec concurrence prévue ou distribuer une charge sur plusieurs fonctions/régions.

Stockage optimisé des données

Le choix de la base de données affecte de façon spectaculaire la latence et le débit. Les applications sans serveur se joignent souvent à DynamoDB (NoSQL) ou à Aurora Serverless (relational). DynamoDB peut gérer des millions de requêtes par seconde si vous concevez vos tables avec des touches de partition appropriées pour éviter les partitions chaudes. Utilisez avec soin des index secondaires mondiaux (IGS) — chaque GSI a sa propre capacité de débit. Pour les lectures à faible latence, activez DynamoDB Accelerator (DAX), un cache en mémoire qui fournit des temps de lecture microseconde. Pour les charges de travail relationnelles, Aurora Serverless v2 auto-échelles dans les unités de capacité d'aurora et prend en charge jusqu'à 128 To de stockage.

Architecture asynchrone et dynamique d'événements

Chaînes synchrones — Fonction A appelant la fonction B, qui appelle la fonction C, introduit la latence série et le throttling en cascade. Par exemple, une passerelle API peut placer une demande de commande sur une file SQS, puis retourner immédiatement une réponse acceptée 202. Une fonction séparée effectue le sondage de la file d'attente et traite l'ordre de manière asynchrone. Ce modèle améliore la latence perçue pour le client et permet au système de tamponner le travail pendant les rafales de trafic.

Calcul des bords

Les services tels que AWS Lambda@Edge et CloudFront vous permettent d'exécuter un code léger aux emplacements de bord CloudFront — plus de 450 points de présence à l'échelle mondiale. Utilisez les fonctions de bord pour l'authentification, la réécriture d'URL, la manipulation d'en-tête ou les tests A/B sans effectuer de voyage vers l'origine. Pour le contenu dynamique, vous pouvez également mettre en cache les réponses au bord pour les TTL courts (par exemple, 1-10 secondes) pour servir des requêtes répétées avec une latence minimale.

Stratégies de conception en profondeur

Fonctions des apatrides avec l'État extérieur

Chaque invocation de fonction doit être indépendante et ne doit rien partager avec d'autres invocations. L'état (données de session, configuration, contexte utilisateur) doit être stocké de manière externe — dans DynamoDB, ElastiCache (Redis/Memcached), ou dans un magasin d'objets. Cela permet à la plate-forme d'évaluer les fonctions de façon arbitraire sans contestation. Pour un débit élevé, batch écrit dans les bases de données à l'aide de l'API [ DynamoDB ou met plusieurs messages dans un seul lot SQS. Pour lire, utilisez DAX ou ElastiCache pour décharger les requêtes répétées de base de données.

Mise en œuvre des calques de cache

La mise en cache est la technique la plus efficace de réduction de la latence.

  • Application cache – dans une instance fonctionnelle, cachez les données fréquemment consultées en mémoire (p. ex., un dictionnaire de paramètres de configuration qui changent rarement).
  • Cachage de la base de données – utilisez DAX ou ElastiCache pour mettre en cache les résultats de requêtes coûteuses. Pour écrire, utilisez un motif écrit ou écrit.
  • CDN/Edge cache[ – les actifs statiques et même les réponses aux API peuvent être mis en cache sur CloudFront. Utilisez les touches de cache basées sur les paramètres de requête, les en-têtes et les cookies.
  • Cache-cache côté client – instruire les navigateurs de mettre en cache des actifs via les en-têtes Cache‐Control.

Surveillez les ratios de frappe du cache et ajustez les politiques d'expulsion. Une stratégie de cache bien adaptée peut réduire la charge d'origine de 80 à 90 % et réduire les temps de réponse de centaines de millisecondes à un seul chiffre.

Migrer les débuts froids

Cold starts se produit lorsqu'un nouvel environnement d'exécution de fonction est initialisé — téléchargement du code, démarrage du code d'exécution et exécution du code d'initialisation. Cela peut ajouter 200 ms à 2 secondes en fonction de l'exécution et de la taille du paquet.

  • Utilisez la fonction provisionnée de la concordance[ pour garder un nombre fixe d'instances au chaud. AWS Lambda frais pour la concordance prévue même en cas de défaut, donc il s'agit d'un compromis entre le coût et la latence.
  • Utilisez des gestionnaires de dépendances spécifiques à la langue (npm, pip) pour inclure seulement ce dont vous avez besoin. Considérez utiliser les calques AWS Lambda pour partager des bibliothèques communes sans ballonner les fonctions individuelles.
  • Optimisez le code d'initialisation. Déplacez les charges lourdes d'importation et de configuration à l'extérieur du gestionnaire afin qu'ils ne fonctionnent qu'une seule fois par conteneur (pendant le démarrage à froid) et non sur chaque invocation.
  • Utilisez des rintemps natifs lorsque c'est possible. Java et .NET démarrages à froid sont notoirement plus lents que Node.js, Python, ou Go. Si vous devez utiliser Java, activez Lambda SnapStart, qui photographie l'environnement d'exécution après initialisation et restaure à partir de lui, réduisant le temps de démarrage à moins de 200 ms.
  • Implémentez un -keep-warm-=" agendar qui ping votre fonction toutes les quelques minutes. Ceci est un hack et pas recommandé pour la production parce qu'il ajoute des coûts et ne garantit pas la chaleur si la fonction balance au-delà des instances chaudes.

Pour les paramètres sensibles à la latence (p. ex. API orientées vers l'utilisateur), utilisez toujours la concordance prévue. Pour les travaux de fabrication par lots ou de fond, les démarrages à froid sont généralement acceptables.

Optimisation de la base de données et conception des requêtes

Les interactions de base de données sont souvent les contributeurs les plus lourds de latence.

  • Design patterns d'accès d'abord Dans DynamoDB, définissez vos schémas d'accès primaires (GetItem, Query) et concevez la clé de partition/sort en conséquence.
  • Utilisez des tableaux globaux pour les déploiements multi-régions afin de réduire la latence inter-régions.
  • Opérations par lots pour réduire les voyages aller-retour. Au lieu d'appeler GetItem pour chacun des 20 enregistrements, utilisez BatchGetItem. Au lieu d'écrire un article à la fois, utilisez BatchWriteItem (max 25 articles par lot).
  • Lire avec une éventuelle cohérence dans la mesure du possible.
  • Utilisez DAX comme cache de lecture pour DynamoDB. DAX réduit les temps de réponse des millisecondes à un seul chiffre aux microsecondes pour les éléments mis en cache.
  • Pour les bases de données relationnelles, utilisez des instructions préparées et la mise en commun des connexions. Aurora Serverless v2 avec l'API de données élimine le besoin de connexions persistantes mais ajoute la latence réseau.

Traitement asynchrone et réglage des files d'attente

Le découplage des voies de requête synchrones avec les files d'attente améliore à la fois la latence perçue et la résilience globale du système.

  • Filtrez le délai de visibilité[ de façon appropriée afin qu'un message défaillant redevienne visible après un délai de traitement (par exemple, le régler à 6× la durée moyenne d'exécution de la fonction).
  • Utiliser le traitement par lots – L'intégration SQS Lambda permet à une seule invocation de recevoir jusqu'à 10 messages (avec ).
  • Configurer les files d'attentes de lettres mortes pour capturer les messages qui échouent après les rétris. Analysez ces derniers pour corriger les bogues ou ajuster le throttling.
  • Pour le traitement des flux[ (Kinesis, DynamoDB Streams), Lambda invocation les enregistre et les traite dans l'ordre par shard. Définissez la taille des lots pour maximiser le débit tout en restant dans le délai d'exécution de la fonction.

Composition des fonctions et communication des services

Dans de nombreuses applications sans serveur, un seul paramètre peut devoir orchestrer des appels vers plusieurs services de backend. Évitez les chaînes série (A appelle B, puis B appelle C). Au lieu de cela, utilisez ]Fonctions d'étape[ pour coordonner les flux de travail asynchrones ou parallèles.Les fonctions d'étape peuvent exécuter simultanément plusieurs actions (par exemple, exécuter trois Lambdas en parallèle et en résultats agrégés), réduisant de façon spectaculaire la latence totale.

Mise en œuvre dans le monde réel: une étude de cas

Une plateforme de commerce électronique de premier plan a migré ses flux de recherche de produits et de caisse vers une pile entièrement sans serveur pour gérer les pics de trafic du vendredi noir.

  • API Gateway[ avec la distribution CloudFront pour le cache de bord global des listes de produits et des actifs statiques.
  • AWS Lambda (Node.js 18) avec une certaine concordance pour la recherche de produits (pour maintenir la latence au démarrage à froid de moins de 50 ms) et une échelle à la demande pour les flux de travail de caisse.
  • DynamoDB avec DAX pour les lectures de catalogue de produits; les opérations d'écriture-gravure (mises à jour d'inventaire) sont directement allés à DynamoDB avec DynamoDB Streams déclenchant une fonction de traitement des commandes asynchrones.
  • SQS pour découpler la soumission d'ordre de l'exécution. Chaque ordre a été demandé, et une fonction Lambda a sondé la file d'attente, en écrivant à Amazon S3 pour le stockage à long terme et l'envoi d'événements à EventBridge.
  • pour orchestrer la validation des paiements, la détection des fraudes et la génération d'étiquettes d'expédition en parallèle.

Pendant le trafic maximal de 1,2 million de demandes par minute, le système a maintenu une latence de moins de 150 ms pour le point de recherche produit et moins de 2 secondes pour la commande (y compris le traitement asynchrone des commandes). Les moteurs de clé étaient le cache de bord (qui a servi à 85% des recherches de produits), la réduction de 60 % de la base de données et la queue asynchrone absorbant les pics sans contrepression sur l'API.

Cette architecture de référence démontre qu'avec la conception intentionnelle — couvrant les démarrages à froid, la mise en cache, le découplage et les exécutions parallèles —, les serveurs sans service peuvent effectivement livrer à la fois un débit élevé et une faible latence à grande échelle.

Conclusion

La conception d'applications sans serveur pour un débit élevé et une faible latence est une question d'application des principes fondamentaux des systèmes distribués : apatridie, cache, découplage asynchrone et stockage efficace des données. La plate-forme sans serveur elle-même fournit le muscle de l'échelle, mais les ingénieurs doivent le guider avec les bons modèles architecturaux. Commencez par des objectifs de performance clairs, tout instrument et itérer sur la base de mesures observées. Rappelez-vous que chaque appel de service et demande de base de données ajoute de la latence — profilez vos goulots d'étranglement et appliquez des optimisations ciblées.