Использование Spring Boot для реализации функции ограничения тока: от теории к практике
Использование Spring Boot для реализации функции ограничения тока: от теории к практике

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

1. Теоретические основы ограничения тока

Общие алгоритмы ограничения тока включают в себя:

  1. Фиксированный алгоритм подсчета окон (Fixed Window Counter):Разделите время на фиксированные окна,Подсчитайте количество запросов в текущем окне.
  2. Счетчик раздвижного окна:существовать Фиксированное количество окон на основе,Ввести раздвижное окно,Уточните детализацию времени.
  3. Алгоритм дырявого ведра:Запросы поступают с постоянной скоростью,Имитируйте воду, текущую из ведра при обработке запроса.
  4. Алгоритм ведра токенов:Система движется к стволу с постоянной скоростью.Добавитьжетон,Возьмите токен при поступлении запроса,Отказ в обслуживании без токена.

2. Spring Boot реализует ограничение тока.

Используя Spring Boot для реализации ограничения тока, вы можете использовать следующие методы:

  1. Реализация ограничения тока на основе фильтра
  2. Используйте сторонние библиотеки, такие как Bucket4j.
  3. Используйте Redis для реализации ограничения распределенного тока

Ниже мы представляем реализацию этих методов соответственно.

Метод 1: реализация ограничения тока на основе фильтра.

1.1 Создание фильтров

Сначала мы создаем фильтр, ограничивающий поток, с помощью AtomicInteger или Semaphore контролировать частоту запросов.

Язык кода:javascript
копировать
javaкопировать импорт org.springframework.stereotype.Component;

импортировать javax.servlet.Filter;
импортировать javax.servlet.FilterChain;
импортировать javax.servlet.FilterConfig;
импортировать javax.servlet.ServletException;
импортировать javax.servlet.ServletRequest;
импортировать javax.servlet.ServletResponse;
импортировать javax.servlet.http.HttpServletResponse;
импортировать java.io.IOException;
импортировать java.util.concurrent.Semaphore;

@Компонент
публичный класс RateLimitingFilter реализует фильтр {

    частный статический финал int MAX_REQUESTS_PER_SECOND = 10;
    частный семафор семафор = новый семафор (MAX_REQUESTS_PER_SECOND);

    @Override
    public void init(FilterConfig filterConfig) выдает ServletException {
    }

    @Override
    public void doFilter (запрос ServletRequest, ответ ServletResponse, цепочка FilterChain)
            выдает IOException, ServletException {
        если (семафор.tryAcquire()) {
            пытаться {
                Chain.doFilter(запрос, ответ);
            } окончательно {
                семафор.выпуск();
            }
        } еще {
            ((HttpServletResponse) ответ).setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
        }
    }

    @Override
    общественный недействительный уничтожить () {
    }
}
1.2 Настройка фильтров

существовать Spring Boot В приложении фильтр прописывается автоматически, нужно только добавить @Component Просто аннотируйте. Однако вы также можете настроить его вручную:

Язык кода:javascript
копировать
javaкопировать импорт кода org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<RateLimitingFilter> loggingFilter() {
        FilterRegistrationBean<RateLimitingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new RateLimitingFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

Способ 2. Используйте Bucket4j для реализации ограничения тока.

2.1 Добавьте зависимости

существовать pom.xml Добавить Bucket4j полагаться:

Язык кода:javascript
копировать
xmlкопироватькод<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>6.2.0</version>
</dependency>
2.2 Создание фильтра ограничения потока
Язык кода:javascript
копировать
javaкопировать импорт кода com.github.bucket4j.Bandwidth;
import com.github.bucket4j.Bucket;
import com.github.bucket4j.Refill;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;

@Component
public class Bucket4jRateLimitingFilter implements Filter {

    private static final int CAPACITY = 10;
    private static final int REFILL_TOKENS = 10;
    private static final Duration REFILL_DURATION = Duration.ofSeconds(1);

    private final Bucket bucket;

    public Bucket4jRateLimitingFilter() {
        Bandwidth limit = Bandwidth.classic(CAPACITY, Refill.greedy(REFILL_TOKENS, REFILL_DURATION));
        this.bucket = Bucket.builder().addLimit(limit).build();
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (bucket.tryConsume(1)) {
            chain.doFilter(request, response);
        } else {
            ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
        }
    }

    @Override
    public void destroy() {
    }
}
2.3 Настройка фильтров

Аналогично первому методу, просто настройте фильтр:

Язык кода:javascript
копировать
javaкопировать импорт кода org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<Bucket4jRateLimitingFilter> loggingFilter() {
        FilterRegistrationBean<Bucket4jRateLimitingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new Bucket4jRateLimitingFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

Способ 3. Используйте Redis для реализации ограничения распределенного тока.

3.1 Добавьте зависимости

существовать pom.xml Добавить Redis и Redisson полагаться:

Язык кода:javascript
копировать
xmlкопироватькод<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.6</version>
</dependency>
3.2 Настройка Redis и Redisson

существовать application.properties Средняя конфигурация Redis:

Язык кода:javascript
копировать
propertiesкопироватькодspring.redis.host=localhost
spring.redis.port=6379
3.3 Создание фильтра ограничения тока Redis
Язык кода:javascript
копировать
javaкопировать импорт кода org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class RedisRateLimitingFilter implements Filter {

    @Autowired
    private RedissonClient redissonClient;

    private RRateLimiter rateLimiter;

    @Bean
    public RRateLimiter rateLimiter() {
        RRateLimiter rateLimiter = redissonClient.getRateLimiter("rateLimiter");
        rateLimiter.trySetRate(RRateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);
        return rateLimiter;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.rateLimiter = rateLimiter();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (rateLimiter.tryAcquire(1)) {
            chain.doFilter(request, response);
        } else {
            ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
        }
    }

    @Override
    public void destroy() {
    }
}
3.4 Настройка фильтров

Как и прежде, настройте фильтр:

Язык кода:javascript
копировать
javaкопировать импорт кода org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<RedisRateLimitingFilter> loggingFilter() {
        FilterRegistrationBean<RedisRateLimitingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new RedisRateLimitingFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

в заключение

существоватьв этом руководстве,Мы представили трисуществовать Spring Boot Методы реализации ограничения тока в:

  1. Простая реализация ограничения тока на основе фильтра.
  2. использовать Сторонние библиотеки Bucket4j Реализуйте ограничение тока.
  3. Используйте Redis для реализации ограничения распределенного тока。

Каждый метод имеет свои преимущества и недостатки и применимые сценарии.,Вы можете выбрать подходящее решение, исходя из ваших конкретных потребностей. Надеюсь, эта статья поможет вам реализовать функцию Реализация ограничений тока в проекте.,Обеспечить стабильность и надежность системы.

Я участвую в последнем конкурсе эссе для специального учебного лагеря Tencent Technology Creation 2024.,Приходите и разделите со мной главный приз!

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.