Rate Limiting en C++ : bibliothèques et implémentation pour la protection d'API

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Rate Limiting en C++ : aperçu des outils et implémentation

\n\n

Le rate limiting (limitation du taux de requêtes) est un mécanisme essentiel pour protéger les services web, les API et les microservices contre les surcharges, les attaques DDoS et l'utilisation irrationnelle des ressources. Dans l'écosystème C++, il existe plusieurs bibliothèques matures et approches pour implémenter le rate limiting. Dans cet article, nous examinerons les principaux algorithmes, les bibliothèques populaires et rédigerons des exemples de code.

\n\n

Algorithmes populaires de rate limiting

\n\n

Avant de choisir une bibliothèque, il est utile de comprendre les algorithmes sous-jacents :

\n\n
    \n
  • Token Bucket (Seau de jetons) — les jetons sont ajoutés à un taux fixe, chaque requête consomme un jeton. S'il n'y a pas de jetons, la requête est rejetée. Simple et efficace.
  • \n
  • Sliding Window (Fenêtre glissante) — prend en compte le nombre de requêtes dans l'intervalle de temps le plus récent (par exemple, 10 requêtes par seconde).
  • \n
  • Fixed Window (Fenêtre fixe) — un simple compteur de requêtes pour une période fixe (par exemple, le compteur est réinitialisé chaque minute).
  • \n
  • Leaky Bucket (Seau percé) — les requêtes sont mises en file d'attente et traitées à un taux constant, l'excédent est rejeté.
  • \n
\n\n

Bibliothèques pour le rate limiting en C++

\n\n

1. Boost.Token Bucket (Boost.Timer + implémentation manuelle)

\n\n

Boost n'a pas d'implémentation prête à l'emploi de token bucket, mais il est facile de l'écrire par-dessus boost::timer ou std::chrono. Cependant, pour les solutions de production, il est préférable d'utiliser des bibliothèques complètes.

\n\n

2. libcppa (C++ Actor Framework)

\n\n

La bibliothèque libcppa (maintenant partie de CAF — C++ Actor Framework) fournit des mécanismes intégrés de rate limiting pour les acteurs. Elle permet de limiter le nombre de messages par unité de temps.

\n\n
#include <caf/all.hpp>\n\nusing namespace caf;\n\nbehavior rate_limited_actor(event_based_actor* self, int max_requests, duration period) {\n    auto limiter = self->make_rate_limiter(max_requests, period);\n    return {\n        [=](const std::string& msg) {\n            if (limiter->try_acquire()) {\n                aout(self) << "Processed: " << msg << endl;\n            } else {\n                aout(self) << "Rate limit exceeded for: " << msg << endl;\n            }\n        }\n    };\n}\n
\n\n

3. userver (de Yandex)

\n\n

Le framework userver de Yandex est une solution puissante pour les services à forte charge en C++. Il inclut un support intégré du rate limiting via components::RateLimiter et utils::TokenBucket.

\n\n
#include <userver/utils/token_bucket.hpp>\n\nusing namespace userver;\n\nint main() {\n    utils::TokenBucket limiter(10, std::chrono::seconds(1)); // 10 requêtes par seconde\n    for (int i = 0; i < 20; ++i) {\n        if (limiter.TryObtain()) {\n            std::cout << "Requête " << i << " autorisée\\n";\n        } else {\n            std::cout << "Requête " << i << " bloquée\\n";\n        }\n        std::this_thread::sleep_for(std::chrono::milliseconds(50));\n    }\n    return 0;\n}\n
\n\n

4. Pistache (framework HTTP avec rate limiting)

\n\n

La bibliothèque Pistache pour créer des serveurs HTTP dispose d'un middleware intégré pour le rate limiting. Exemple :

\n\n
#include <pistache/endpoint.h>\n#include <pistache/router.h>\n#include <pistache/http.h>\n\nusing namespace Pistache;\n\nint main() {\n    Http::Endpoint server(Address(Ipv4::any(), Port(9080)));\n    auto router = std::make_shared<Rest::Router>();\n    \n    // Rate limiter intégré : 5 requêtes par seconde\n    router->addMiddleware(Http::Middleware::RateLimit(5, std::chrono::seconds(1)));\n    \n    Rest::Routes::Get(*router, "/api/resource", [](const Rest::Request& req, Http::ResponseWri                    

Recommendations