Цель ограничения тока состоит в том, чтобы защитить систему, ограничивая скорость одновременного доступа/запросов или ограничивая скорость запросов в течение временного окна. Как только ограничивающая ставка достигнута, услуга может быть отказано.
Несколько дней назад я прочитал план использования гуава для достижения одноприменения потока. Ссылка "Redis in Action" для реализации версии Jedis, которые являются ограничениями на уровне бизнеса. Общие стратегии ограничения тока в реальных сценариях:
Nginx Access Leacher Light
В соответствии с определенными правилами, такими как номер учетной записи, IP, логика системного вызова и т. Д., Чтобы ограничить ток на уровне Nginx
Система бизнес -приложений.
Контроль трафика через бизнес -код можно назвать семафором, который можно понимать как блокировку, что может ограничить, сколько процессов можно получить одновременно.
Реализация кода
import redis.clients.jedis.Jedis;import redis.clients.jedis.Transaction;import redis.clients.jedis.ZParams;import java.util.List;import java.util.UUID;/** * @email [email protected] * @data 2017-08 */public class RedisRateLimiter { private static final String BUCKET = "ВЕДРО"; частная статическая конечная строка Bucket_count = "bucket_count"; Частная статическая конечная строка Bucket_monitor = "bucket_monitor"; static String accireTokenFrombucket (jedis jedis, int limit, long Timeout) {string идентификатор = uuid.randomuuid (). ToString (); long now = System.currentTimeMillis (); Транзакция транзакции = jedis.multi (); // Удалить Semaphore Transaction.zremrangebyscore (bucte_monitor.getbytes (), "-inf" .getbytes (), string.valueof (сейчас - timeout) .getbytes ()); Zparams params = new zparams (); params.weightsbydouble (1,0,0,0); Transaction.zinterstore (ведро, параметры, ведро, bucket_monitor); // счетчика с самостоятельностью. Список <object> results = transaction.exec (); длинный счетчик = (длинный) Результаты. Get (Results.Size () - 1); транзакция = jedis.multi (); transaction.zadd (bucket_monitor, теперь, идентификатор); Transaction.zadd (ведро, счетчик, идентификатор); Transaction.Zrank (ведро, идентификатор); Результаты = transaction.exec (); // Получить рейтинг, чтобы определить, получил ли запрос полученный семафор длинный ранг = (long) results.get (result.size () - 1); if (Rank <Limit) {return Identifier; } else {// не было получено семафор, помещенное в Redis до очистки транзакции = jedis.multi (); Transaction.zrem (bucket_monitor, идентификатор); Transaction.zrem (ведро, идентификатор); Transaction.exec (); } return null; }}
Вызов
Тестовый интерфейс -звонок
@Getmapping ("/") public void index (httpservletresponse response) бросает ioexception {jedis jedis = jedispool.getresource (); String token = redisratelimiter.acquiretokenfrombucket (jedis, limit, timeout); if (token == null) {response.senderror (500); } else {// todo your Business Logic} jedispool.returnresource (jedis);}оптимизация
Оптимизировать код с аннотацией Interceptor +
Перехватчик
@Configurationstatic class webmvcconfigurer extends webmvcconfigureradapter {private logger logger = loggerfactory.getlogger (webmvcconfigurer.class); @Autowired jedispool jedispool; public void AddInterceptors (реестр ReceptorgeRegistry) {Registry.Adinterceptor (new HandlerInterceptorAdapter () {public boolean prehandle (httpservletrequest, httpservletresponse, ответный ответ), метод, метод {handlermethod handlermethod = (handlerermethod) Handler; Handlermethod); RateLimiter rateLimiter = метод. if (token == null) {response.senderror (500); }}Определение аннотации
/** * @email [email protected] * @data 2017-08 * Текущая лимитная аннотация */@target (elementtype.method) @retention (streationpolicy.runtime) @documentedpublic @Interface ratelimiter {int Limit () по умолчанию 5; int timeout () по умолчанию 1000;}
использовать
@Ratelimiter (Limit = 2, Timeout = 5000) @GetMapping ("/test") public void -test () {}Одновременное тестирование
Инструменты: Apache-Jmeter-3.2
ПРИМЕЧАНИЕ. Интерфейс, который не получил возврата семафора 500, статус является красным, интерфейс, который получил семифор возврата 200, статус зеленый.
Когда семафор запроса ограниченного запроса составляет 2, 5 потоков отправляются:
Когда семафор лимитного запроса составляет 5, 10 потоков отправляются:
материал
Реализация на основе Reids + Lua
Суммировать
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.