Passer au contenu principal

Performances de l'API : limitation de débit, pagination et traitement asynchrone

Créez des API hautes performances avec des algorithmes de limitation de débit, une pagination basée sur le curseur, des files d'attente de tâches asynchrones et les meilleures pratiques de compression des réponses.

E
ECOSIRE Research and Development Team
|15 mars 202614 min de lecture2.7k Mots|

Votre API est aussi rapide que son point de terminaison le plus lent en cas de charge maximale. Un seul point de terminaison non optimisé qui conserve les connexions à la base de données pendant 5 secondes peut épuiser votre pool de connexions et provoquer des pannes en cascade sur l'ensemble de votre plate-forme.

Fait partie de notre série Performance et scalabilité

Lire le guide complet

Votre API est aussi rapide que son point de terminaison le plus lent en cas de charge maximale. Un seul point de terminaison non optimisé qui conserve les connexions à la base de données pendant 5 secondes peut épuiser votre pool de connexions et provoquer des pannes en cascade sur l'ensemble de votre plate-forme. L'ingénierie des performances des API se concentre sur trois piliers : protéger votre API contre la surcharge (limitation du débit), gérer efficacement de grands ensembles de données (pagination) et retirer les opérations coûteuses du cycle de requête (traitement asynchrone).

Points clés à retenir

  • Le compartiment à jetons et la fenêtre coulissante sont les deux algorithmes de limitation de débit qui couvrent 95 % des cas d'utilisation. Choisissez selon que vous souhaitez une tolérance en rafale ou une application stricte.
  • La pagination basée sur le curseur surpasse la pagination décalée pour les grands ensembles de données car elle évite de compter les lignes ignorées
  • Le traitement asynchrone avec les files d'attente de tâches réduit les temps de réponse P95 en déplaçant l'envoi d'e-mails, la génération de PDF et la livraison de webhooks hors du chemin de requête.
  • La compression des réponses avec Brotli réduit la taille des charges utiles de 70 à 85 %, ce qui se traduit directement par un rendu plus rapide côté client.

Algorithmes de limitation de débit

La limitation de débit protège votre API contre les abus, garantit une allocation équitable des ressources et empêche les pannes en cascade lors des pics de trafic. L'algorithme que vous choisissez détermine la manière dont les rafales sont gérées et le degré de prévisibilité du comportement limitant pour les consommateurs.

AlgorithmeGestion des rafalesUtilisation de la mémoirePrécisionIdéal pour
Fenêtre fixePermet une rafale 2x à la limite de la fenêtreTrès faibleFaibleCas d'utilisation simples, API internes
Journal de fenêtre coulissantePas de salves, précisÉlevé (stocke les horodatages)Très élevéAPI financières, stricte conformité
Comptoir à fenêtre coulissanteRafale de limite minimaleFaibleÉlevéAPI publiques à usage général
Seau de jetonsPermet des rafales contrôléesFaibleModéréAPI avec des modèles de rafales naturels
Seau qui fuitFluidifie tout le traficFaibleÉlevéAPI nécessitant un débit constant

Seau de jetons

L’algorithme du token bucket est le choix le plus pratique pour la plupart des API. Un compartiment contient des jetons jusqu'à une capacité maximale. Les jetons sont ajoutés à un taux fixe (le taux de recharge). Chaque requête consomme un jeton. Si le compartiment est vide, la demande est rejetée ou mise en file d'attente.

Le principal avantage du compartiment à jetons est la tolérance aux rafales. Si un client n'a pas effectué de requêtes depuis un certain temps, son bucket est plein et il peut effectuer une rafale de requêtes jusqu'à la capacité du bucket. Cela correspond à des modèles d'utilisation naturels : un client qui charge un tableau de bord peut effectuer 20 requêtes en succession rapide, puis rien pendant 30 secondes.

Exemple de configuration pour une API de commerce électronique :

  • Taille du bucket : 100 jetons
  • Taux de recharge : 10 jetons par seconde
  • Cela permet des rafales allant jusqu'à 100 requêtes tout en maintenant 10 requêtes par seconde à long terme

Compteur à fenêtre coulissante

Le compteur à fenêtre coulissante combine la précision du journal à fenêtre coulissante avec l'efficacité de la mémoire d'une fenêtre fixe. Il gère les compteurs pour la fenêtre actuelle et la fenêtre précédente, puis calcule un nombre pondéré en fonction de la distance parcourue par la demande dans la fenêtre actuelle.

Pour une fenêtre de 60 secondes évaluée à 45 secondes, le nombre effectif est : (nombre de fenêtres précédent * 0,25) + (nombre de fenêtres actuel). Cela élimine le problème de rafale de limites des fenêtres fixes sans stocker les horodatages de requêtes individuelles.

Implémentation avec Redis

Redis est le magasin de support standard pour la limitation de débit distribuée, car il fournit des opérations d'incrémentation atomique avec TTL. Utilisez INCR avec EXPIRE pour les fenêtres fixes, ou des ensembles triés avec ZADD et ZRANGEBYSCORE pour les fenêtres coulissantes. Pour le compartiment de jetons, les scripts Redis Lua fournissent des opérations de vérification et de décrémentation atomiques.

Les en-têtes de limitation de débit communiquent les limites aux consommateurs d'API :

  • X-RateLimit-Limit -- nombre maximum de requêtes autorisées dans la fenêtre
  • X-RateLimit-Remaining -- requêtes restant dans la fenêtre actuelle
  • X-RateLimit-Reset -- Horodatage Unix lors de la réinitialisation de la fenêtre
  • Retry-After -- secondes jusqu'à ce que le client doive réessayer (sur 429 réponses)

Stratégies de pagination

Chaque point de terminaison de liste doit être paginé. Le renvoi d’ensembles de résultats illimités gaspille de la bande passante, met à rude épreuve la base de données et risque d’entraîner des erreurs de délai d’attente à mesure que les données augmentent.

Pagination décalée

La pagination décalée utilise les clauses SQL LIMIT et OFFSET. Le client demande ?page=3&limit=20 et le serveur traduit en OFFSET 40 LIMIT 20.

Avantages :

  • Simple à mettre en œuvre et à comprendre
  • Les clients peuvent accéder directement à n'importe quelle page
  • Le nombre total active l'interface utilisateur "Page X sur Y"

Inconvénients :

  • Les performances se dégradent avec des décalages élevés - OFFSET 1000000 analyse toujours 1 000 000 de lignes avant de renvoyer des résultats
  • Résultats incohérents lorsque les données changent entre les pages (les lignes changent à mesure que de nouvelles données sont insérées ou supprimées)
  • La requête de nombre total (COUNT(*)) peut être coûteuse sur les grandes tables

Pagination basée sur le curseur

La pagination basée sur un curseur utilise un curseur opaque (généralement une clé primaire codée ou un horodatage) pour marquer la position dans le jeu de résultats. Le client demande ?cursor=abc123&limit=20 et le serveur utilise le curseur comme clause WHERE : WHERE id > decoded(abc123) LIMIT 20.

Avantages :

  • Performances constantes quelle que soit la position dans l'ensemble de données - pas de numérisation offset
  • Résultats stables même lorsque les données changent entre les pages
  • Ajustement naturel pour un défilement infini et des flux en temps réel

Inconvénients :

  • Impossible d'accéder à des pages arbitraires (pas de "Aller à la page 50")
  • Plus complexe à mettre en œuvre, notamment avec les ordres de tri multi-colonnes
  • Le nombre total doit être fourni séparément si nécessaire

Quelle pagination utiliser

ScénarioRecommandationRaison
Tableaux de données d'administration avec numéros de pageDécalageLes utilisateurs s'attendent à une navigation dans les pages
Défilement infini mobileCurseurPerformance à toutes les profondeurs
API consommée par les intégrationsCurseurPagination stable pour le traitement par lots
Petits ensembles de données (moins de 10 000 lignes)SoitLa différence de performances est négligeable
Grands ensembles de données (plus de 100 000 lignes)CurseurLe décalage devient inutilisablement lent
Flux en temps réel (chat, notifications)CurseurCohérence à mesure que de nouvelles données arrivent

Format de réponse de pagination

Une réponse de pagination bien conçue comprend des métadonnées dans lesquelles les clients doivent naviguer :

{
  "data": [],
  "pagination": {
    "total": 15432,
    "limit": 20,
    "hasMore": true,
    "nextCursor": "eyJpZCI6MTAwfQ=="
  }
}

Traitement asynchrone avec les files d'attente de tâches

Les points de terminaison d'API synchrones doivent renvoyer des réponses dans un délai de 200 ms. Toute opération qui prend plus de temps (envoi d'e-mails, génération de PDF, traitement d'images, appel d'API externes, exécution de rapports) doit être déplacée vers une file d'attente de tâches en arrière-plan.

Le modèle de file d'attente des tâches

  1. Le point de terminaison de l'API valide la demande et crée un enregistrement de tâche
  2. Le travail est placé dans une file d'attente (Redis, RabbitMQ, SQS)
  3. L'API renvoie immédiatement avec une réponse 202 Accepted et un ID de travail
  4. Un processus de travail récupère le travail et l'exécute de manière asynchrone
  5. Le client interroge l'état de la tâche ou reçoit un rappel de webhook une fois terminé.

Cas d'utilisation asynchrone courants

Envoi d'e-mails -- Les opérations SMTP prennent entre 500 ms et 3 s selon le fournisseur. La mise en file d'attente des e-mails réduit le temps de réponse de l'API et permet une logique de nouvelle tentative en cas d'échecs transitoires sans bloquer l'utilisateur.

Génération PDF -- La génération de factures, de rapports ou de fichiers d'exportation est gourmande en CPU et en mémoire. Leur exécution sur des Workers dédiés évite les conflits de ressources avec la gestion des requêtes API.

Livraison de webhooks : les webhooks sortants dépendent de la disponibilité du serveur tiers. Mettez en file d'attente les livraisons de webhooks avec de nouvelles tentatives d'interruption exponentielle (1 s, 2 s, 4 s, 8 s, jusqu'à 5 minutes) pour gérer les pannes temporaires sans bloquer votre système.

Importation et exportation de données : le traitement des téléchargements CSV comportant 100 000 lignes ne devrait jamais avoir lieu au cours d'un cycle de requête. Acceptez le téléchargement, renvoyez un ID de tâche et traitez les lignes par lots.

Sélection de la file d'attente

Technologie de file d'attenteIdéal pourConsidérations
BullMQ (soutenu par Redis)Applications Node.js, intégration NestJSExcellente expérience de développement, tableau de bord intégré
LapinMQSystèmes multilingues, routage complexeMature, prend en charge les modèles d'accusé de réception des messages
AWSSQSInfrastructure gérée et sans serveurPas de gestion de serveur, paiement par message
KafkaStreaming d'événements, haut débitExagération pour les files d'attente de tâches simples, excellente pour le sourcing d'événements

Optimisation des réponses

Au-delà de la logique applicative, la réponse elle-même peut être optimisée en termes de taille et de vitesse de livraison.

Compression

Activez la compression des réponses pour réduire la taille des charges utiles sur le réseau. Les algorithmes de compression modernes réduisent considérablement les charges utiles basées sur le texte (JSON, HTML, CSS, JavaScript).

AlgorithmeTaux de compressionCoût du processeurPrise en charge du navigateur
gzip60-75% de réductionFaibleUniversel
Brotli70-85% de réductionModéréTous les navigateurs modernes
zstd70-85% de réductionFaibleÉmergent (pas encore universel)

Utilisez Brotli pour les actifs statiques (pré-compressés au moment de la construction) et gzip comme solution de secours pour les réponses dynamiques. Dans NestJS, le middleware de compression gère cela automatiquement, mais en production, laissez Nginx gérer la compression pour décharger le processeur de votre serveur d'applications.

Sélection de champ

Autorisez les consommateurs d’API à demander uniquement les champs dont ils ont besoin. GraphQL le fait de manière inhérente, mais les API REST peuvent prendre en charge la sélection de champs avec un paramètre de requête ?fields=id,name,price. Cela réduit la taille de la charge utile et peut optimiser les requêtes de base de données en sélectionnant uniquement les colonnes nécessaires.

En-têtes de mise en cache des réponses

Définissez les en-têtes Cache-Control appropriés sur les réponses de l'API. Les points de terminaison de la liste publique (produits, catégories) peuvent utiliser Cache-Control: public, max-age=300 pour mettre en cache pendant 5 minutes. Les points de terminaison authentifiés doivent utiliser Cache-Control: private, no-cache pour empêcher la mise en cache CDN tout en autorisant la mise en cache du navigateur avec revalidation.

Pour en savoir plus sur les stratégies de mise en cache, consultez notre guide détaillé sur la mise en cache Redis, CDN et HTTP.


Gestion des connexions

Les connexions aux bases de données et HTTP sont des ressources limitées qui doivent être gérées avec soin en cas de charge.

Regroupement de connexions à la base de données

Un pool de connexions gère un ensemble de connexions de base de données réutilisables. Sans pooling, chaque requête API ouvre une nouvelle connexion à la base de données (surcharge de 50 à 100 ms) et la ferme après la réponse. Avec le pooling, les requêtes empruntent des connexions au pool et les renvoient une fois terminées.

Formule de dimensionnement du pool : connexions = (core_count * 2) + effective_spindle_count. Pour un serveur à 4 cœurs avec stockage SSD, 10 à 20 connexions par instance d'application constituent un bon point de départ. Surveillez l'utilisation du pool : si elle dépasse régulièrement 80 %, augmentez la taille du pool ou optimisez la durée des requêtes.

HTTP Keep-Alive

Activez HTTP keep-alive pour les connexions aux services en amont (bases de données, Redis, API externes). Cela réutilise les connexions TCP au lieu d'en établir de nouvelles par requête, éliminant ainsi la prise de contact TCP et la surcharge de négociation TLS (50 à 200 ms par nouvelle connexion).


Questions fréquemment posées

Quelles limites de débit dois-je définir pour une API publique ?

Commencez avec des limites prudentes et ajustez en fonction des modèles d'utilisation légitimes. Un point de départ courant est de 100 requêtes par minute pour les utilisateurs authentifiés et de 20 requêtes par minute pour les utilisateurs anonymes. Surveillez les taux de réponse de 429 : si les utilisateurs légitimes atteignent fréquemment les limites, augmentez-les. Fournissez des limites plus élevées pour les niveaux d'API premium.

Comment gérer la pagination lorsque les données changent entre les pages ?

La pagination basée sur le curseur gère cela naturellement car elle s'ancre à une position spécifique dans les données triées. Avec la pagination offset, le document résultant peut se décaler entre les pages. Pour les cas d'utilisation critiques (rapports financiers, exportations de données), capturez les données au début de la pagination et paginer par-dessus l'instantané.

Dois-je utiliser REST ou GraphQL pour les performances ?

REST avec sélection de champs et mise en cache appropriée est plus rapide pour les points de terminaison simples et bien définis. GraphQL élimine la sur-récupération et la sous-récupération pour les exigences de données complexes, mais ajoute une surcharge d'analyse des requêtes et rend la mise en cache HTTP plus difficile. Utilisez REST pour les API publiques ayant des besoins de mise en cache et GraphQL pour les API internes répondant à des exigences complexes en matière de données frontales.

Comment puis-je surveiller les performances de l'API en production ?

Suivez les temps de réponse P50, P95 et P99 par point de terminaison. Définissez des alertes sur P95 violant votre SLO (généralement 200 à 500 ms). Utilisez le traçage distribué pour décomposer le temps passé dans la base de données, le cache, les services externes et la logique des applications. Consultez notre guide sur surveillance et observabilité pour une configuration détaillée.


Quelle est la prochaine étape

Commencez par auditer les points de terminaison de votre API pour détecter les paginations manquantes, les points de terminaison publics non protégés sans limitation de débit et les opérations synchrones qui devraient être asynchrones. Ces trois changements réduisent généralement les temps de réponse du P95 de 50 à 70 % et évitent les incidents de production les plus courants.

Pour une perspective complète de l'ingénierie des performances, consultez notre guide des piliers sur la mise à l'échelle de votre plateforme commerciale. Pour connaître la couche de base de données qui alimente votre API, lisez notre guide d'optimisation des requêtes.

ECOSIRE construit des API hautes performances pour les plateformes métiers sur Odoo ERP et des architectures personnalisées. Contactez-nous pour un examen des performances de l'API.


Publié par ECOSIRE — aider les entreprises à évoluer grâce à des solutions basées sur l'IA dans Odoo ERP, Shopify eCommerce et OpenClaw AI.

E

Rédigé par

ECOSIRE Team

Rédaction technique

L'équipe de rédaction technique d'ECOSIRE traite d'Odoo ERP, de l'e-commerce avec Shopify, des agents IA, de l'analytique avec Power BI, de l'automatisation avec GoHighLevel et des bonnes pratiques du logiciel d'entreprise. Nos guides aident les entreprises à prendre des décisions technologiques éclairées.

ECOSIRE

Développez votre entreprise avec ECOSIRE

Solutions d'entreprise pour l'ERP, le commerce électronique, l'IA, l'analyse et l'automatisation.

Plus de Performance et scalabilité

Débogage et surveillance des webhooks : le guide de dépannage complet

Maîtrisez le débogage des webhooks avec ce guide complet couvrant les modèles de défaillance, les outils de débogage, les stratégies de nouvelle tentative, les tableaux de bord de surveillance et les meilleures pratiques de sécurité.

Tests de charge k6 : testez sous contrainte vos API avant le lancement

Maîtrisez les tests de charge K6 pour les API Node.js. Couvre les montées en puissance des utilisateurs virtuels, les seuils, les scénarios, HTTP/2, les tests WebSocket, les tableaux de bord Grafana et les modèles d'intégration CI.

Configuration de production Nginx : SSL, mise en cache et sécurité

Guide de configuration de production Nginx : terminaison SSL, HTTP/2, en-têtes de mise en cache, en-têtes de sécurité, limitation de débit, configuration du proxy inverse et modèles d'intégration Cloudflare.

Odoo Performance Tuning : PostgreSQL et optimisation du serveur

Guide expert sur le réglage des performances d’Odoo 19. Couvre la configuration PostgreSQL, l'indexation, l'optimisation des requêtes, la mise en cache Nginx et le dimensionnement du serveur pour les déploiements d'entreprise.

Test et surveillance des agents IA en production

Un guide complet pour tester et surveiller les agents IA dans les environnements de production. Couvre les cadres d'évaluation, l'observabilité, la détection des dérives et la réponse aux incidents pour les déploiements OpenClaw.

Agents de surveillance de la conformité avec OpenClaw

Déployez des agents OpenClaw AI pour une surveillance continue de la conformité. Automatisez les contrôles réglementaires, l’application des politiques, la génération de pistes d’audit et les rapports de conformité.