Серия микросервисов: сервисный шлюз Spring Cloud Gateway, ограничивающая текущую конфигурацию

задняя часть Spring Cloud
Серия микросервисов: сервисный шлюз Spring Cloud Gateway, ограничивающая текущую конфигурацию

предыдущий постСерия Microservice: Начало работы с сервисным шлюзом Spring Cloud Gatewayмы изучилиSpring Cloud GatewayНекоторые из вводных знаний, сегодня мы узнаем, как использовать Spring Cloud Gateway для достижения текущего ограничения.

Без лишних слов, давайте начнем сегодняшнее исследование.

Конфигурация ограничения тока

1. Родственные понятия

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

Общие алгоритмы ограничения тока:计数器алгоритм,漏桶(Leaky Bucket)алгоритм,令牌桶(Token Bucket)алгоритм.

Spring Cloud Gatewayофициально предоставленRequestRateLimiterGatewayFilterFactoryзавод фильтров, использованиеRedis а такжеLuaскрипт реализованведро с жетонамиПуть.

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

Действие по высвобождению токена является непрерывным. Если количество токенов в корзине достигает верхнего предела, токен будет сброшен. Поэтому и возникает такая ситуация.В корзине всегда большое количество доступных токенов.В это время входящие запросы могут выполняться напрямую с токенами.Например,если qps установлено на 100, то через секунду после инициализация ограничителя тока завершена, ведро будет Токенов уже 100. На данный момент сервис запущен не полностью. Когда услуга предоставляется внешнему миру, ограничитель тока выдерживает мгновенные 100 запросов. Следовательно, только когда в ведре нет токена, запрос будет ожидать, что эквивалентно выполнению с определенной скоростью.

Нашел картинку в сети:

image.png

2. Кодовый бой

Как указано выше,Spring Cloud Gatewayофициально предоставленRequestRateLimiterGatewayFilterFactoryзавод фильтров, использованиеRedis а такжеLuaСкрипт реализуетведро с жетонами Путь.

Поэтому нам также нужно ввести реактивные зависимости redis

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>

application.ymlконфигурационный файл

server:
  port: 8080

spring:
  application:
    name: api-gateway
  redis:
    host: localhost
    port: 6379
    password:
  cloud:
    gateway:
      routes:
        - id: cloud-gateway
          uri: http://192.168.1.211:8088/
          predicates:
            - Path=/ytb/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1   # 令牌桶每秒填充速率
                redis-rate-limiter.burstCapacity: 2   # 令牌桶总容量
                key-resolver: "#{@pathKeyResolver}"   # 使用 SpEL 表达式按名称引用 bean

В приведенном выше файле конфигурации настройтеredisинформацию и настроитьRequestRateLimiterФильтр ограничения тока для фильтра необходимо настроить с тремя параметрами:

  • burstCapacity, общая емкость корзины токенов.
  • replenishRate, средняя скорость заполнения корзины токенов в секунду.
  • key-resolver, имя объекта bean-компонента синтаксического анализатора для ключа, используемого для регулирования. Он использует выражение SpEL для получения объекта bean-компонента из контейнера Spring на основе #{@beanName}.

записыватьURIТекущий класс конфигурации правила ограничения

@Configuration
public class KeyResolverConfiguration {
    @Bean
    public KeyResolver pathKeyResolver(){
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

Затем запустите Redis локально, перезапустите проект, мы можем проверить, чтобы увидеть эффект.

image.png

Это по-прежнему исходный интерфейс. После того, как мы быстро обновим его несколько раз, мы обнаружим, что он возвращаетHTTP ERROR 429

image.png

Это показывает, что наш текущий лимит сыграл свою роль, и текущий лимит был успешно просмотрен.redisДва ключа хранятся в

request_rate_limiter.{file/getFileType}.timestamp
request_rate_limiter.{xxx}.tokens

image.png

Другие действующие правила ограничения

Ограничение тока параметра:key-resolver: "#{@parameterKeyResolver}"(Следующая конфигурация требует, чтобы параметр userId был передан в пути запроса)

@Bean
public KeyResolver parameterKeyResolver()
{
	return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}

Ограничение тока IP:key-resolver: "#{@ipKeyResolver}"

@Bean
public KeyResolver ipKeyResolver()
{
	return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

Правила фильтрации (Фильтр)

правила фильтрации пример иллюстрировать
PrefixPath - PrefixPath=/app добавить приложение перед путем запроса
RewritePath - RewritePath=/test, /app/test Посетите localhost:9022/test, запрос будет перенаправлен на localhost:8001/app/test.
SetPath SetPath=/app/{path} Задайте путь через шаблон, правило переадресации добавит приложение перед путем, {path} представляет исходный путь запроса.
RedirectTo перенаправить
RemoveRequestHeader удалить заголовок запроса

StripRefix

StripPrefixуказывает количество перехваченных путей

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: cloud-gateway
          uri: http://192.168.1.211:8088
          predicates:
            - Path=/ytb/my/**
          filters:
            - StripPrefix=2

Вот адрес доступаhttp://localhost:8080/ytb/my/file/getFileTypeбудет отправленоhttp://192.168.1.211:8088/file/getFileTypeадрес.

Междоменная конфигурация

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOriginPatterns: "*"
            allowed-methods: "*"
            allowed-headers: "*"
            allow-credentials: true
            exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"

Конечно, если вы используетеnginxЕсли вы настраиваете прокси для междоменного решения, вам не нужно добавлять междоменную поддержку.