Как реализовать ограничение скорости на основе клиентского токена в Spring?

Я разрабатываю простой REST API, используя Spring 3 + Spring MVC. Аутентификация будет выполняться через OAuth 2.0 или базовую аутентификацию с токеном клиента с использованием Spring Security. Это все еще обсуждается. Все подключения будут принудительно осуществляться через SSL-соединение.

Я искал информацию о том, как реализовать ограничение скорости, но не похоже, чтобы там было много информации. Реализация должна быть распределенной, поскольку она работает на нескольких веб-серверах.

Например, если есть три API-сервера A, B, C, а количество клиентов ограничено 5 запросами в секунду, то клиент, который делает 6 таких запросов, обнаружит, что запрос к C отклонен с ошибкой.

A recieves 3 requests   \
B receives 2 requests    | Executed in order, all requests from one client.
C receives 1 request    /

Он должен работать на основе токена, включенного в запрос, так как один клиент может делать запросы от имени многих пользователей, и скорость каждого пользователя должна быть ограничена, а не IP-адрес сервера.

Будет установлено несколько (2–5) веб-серверов за балансировщиком нагрузки HAProxy. Существует поддержка Cassandra, и используется memcached. Веб-серверы будут работать на Jetty.

Одним из возможных решений может быть написание пользовательского фильтра безопасности Spring, который извлекает токен и проверяет, сколько запросов было сделано с ним за последние X секунд. Это позволило бы нам делать некоторые вещи, такие как разные ограничения скорости для разных клиентов.

Есть предложения, как это можно сделать? Есть ли существующее решение или мне придется написать свое собственное решение? Раньше я не занимался инфраструктурой веб-сайтов.

16
задан aj.esler 16 April 2012 в 23:39
поделиться