Практика SpringCloud Alibaba Microservices 5 — Текущее ограничение и объединение

Java

Введение: эта статья является пятой статьей в серии статей о борьбе с микросервисами Spring Cloud Alibaba.Основное содержание заключается в использовании Sentinel для добавления функции ограничения тока и предохранителя к микросервисам, чтобы предотвратить перетаскивание сервисов приложений из-за нештатных ситуаций. Серия статей, добро пожаловать, чтобы продолжать обращать внимание.

Введение

SentinelЭто упрощенная структура управления потоком для распределенной службы, которая в основном использует поток в качестве точки входа и поддерживает стабильность системы в нескольких измерениях, таких как управление потоком, снижение производительности и защита системы от нагрузки. В системе SpringCloudsentinelОсновная цель состоит в том, чтобы заменить функцию оригинального Hystrix.По сравнению с Hystrix, уровень изоляции Sentinel более совершенен.Предоставляемая панель мониторинга может изменять текущие правила ограничения и слияния в режиме онлайн, и она более удобна в использовании. Для получения более подробной информации перейдите наОфициальный сайт Сентинел.

Базовая подготовка

Чтобы использовать токоограничивающие предохранители, предоставляемые Sentinel, необходимо выполнить следующие приготовления:

  • Установить Сентинел
    Я уже освещал эту часть в первом выпускеSpringCloud Alibaba Microservices Практика 1 — Базовая подготовка средыЭто было упомянуто в тексте, вы можете прочитать его.
  • Представляем Стража
    Внесите компоненты Sentinel в файл POM, которые необходимо настроить для службы предохранителей, ограничивающих ток.
<!--Sentinel-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

  • пользовательский ресурс@SentinelResource
    Нам просто нужно добавить соответствующий метод@SentinelResourceАннотируйте его, чтобы он стал ресурсом, распознаваемым Sentinel. Такие как:
@GetMapping("/account/getByCode/{accountCode}")
@SentinelResource(value = "getByCode")
public ResultData<AccountDTO> getByCode(@PathVariable(value = "accountCode") String accountCode){
    log.info("get account detail,accountCode is :{}",accountCode);
    AccountDTO accountDTO = accountService.selectByCode(accountCode);
    return ResultData.success(accountDTO);
}

  • Добавьте адрес сервера sentinel в файл конфигурации
server:
  port: 8010
spring:
  application:
    name: account-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.0.107:8848/
    sentinel:
      transport:
      # sentinel服务端地址
        dashboard: 192.168.0.107:8858
      # 取消延迟加载
      eager: true

После вышеуказанных шагов мы готовы использовать базовую среду Sentinel.Далее давайте рассмотрим конкретную конфигурацию токоограничивающего предохранителя.

Ограничение

Концептуальная записка

режиссерaccout-serviceЭто основная служба, и мы обнаружили, что максимальная грузоподъемность службы составляет 60 в результате стресс-тестирования. если когда-нибудьaccount-serviceКоличество запросов взлетело до 600, значит сервис должен быть напрямую ггг. так что для защиты нашихaccout-service, настроим для него текущее ограничивающее правило.Если будет больше 60 запросов в секунду, извините, я просто выброшу и не буду обрабатывать, а потом выкину исключение потребителю, пытающемуся меня утащить вниз , хм, никак! .image.png

В целом, текущее ограничение предназначено для защиты собственной системы путем ограничения вызовов вызывающего абонента самому себе.

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

Идеал пухленький, реальность худенькая. Поскольку я не очень хорошо разбираюсь в инструментах стресс-тестирования, таких как Jmeter, для удобства тестирования мы будемaccout-serviceПороговое значение количества запросов в секунду для одной машины установлено равным 5. Если количество запросов в секунду превышает 5, оно будет напрямую отброшено.image.png

Имя ресурса здесь то, что мы используем@SentinelResourceАннотируйте пользовательские ресурсы.

Откройте браузер, быстро обновите браузер, когда запрос книг в секунду превысит 5, вы увидите следующую ошибку:image.png

В журнале серверной службы вы увидите следующий журнал ошибок:

2019-12-10 14:22:31,948 ERROR [dispatcherServlet]:175 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause
com.alibaba.csp.sentinel.slots.block.flow.FlowException: null

Не паникуйте, это показывает, что наша цель достигнута, и текущий лимит выполнен успешно!

пользовательское исключение

мы можем пройти@SentinelResourceдобавлено вblockHandlerпараметр, добавьте к нему собственный метод исключения. Такие как:

@GetMapping("/account/getByCode/{accountCode}")
@SentinelResource(value = "getByCode",blockHandler = "handleException")
public ResultData<AccountDTO> getByCode(@PathVariable(value = "accountCode") String accountCode){
    log.info("get account detail,accountCode is :{}",accountCode);
    AccountDTO accountDTO = accountService.selectByCode(accountCode);
    return ResultData.success(accountDTO);
}
/**
 * 自定义异常策略
 * 返回值和参数要跟目标函数一样,参数可以追加BlockException
 */
public ResultData<AccountDTO> handleException(String accountCode,BlockException exception){
    log.info("flow exception{}",exception.getClass().getCanonicalName());
    return ResultData.fail(900,"达到阈值了,不要再访问了!");
}

Обратите внимание, что параметры и возвращаемое значение пользовательского метода исключения должны быть такими же, как у целевого метода, и параметры могут быть добавлены с помощью BlockException.

Эффект следующий:
image.png

Гораздо элегантнее, чем предыдущая страница с ошибкой!

постоянная конфигурация

потому чтоSentinelКонфигурация по умолчанию помещается в память всякий раз, когда приложение перезагружается илиsentinelДанные будут потеряны после перезапуска Мы используем Nacos в качестве центра конфигурации для сохранения текущей конфигурации ограничения.

  • Измените файл pom и импортируйтеsentinel-datasource-nacosкомпоненты
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

  • Измените application.yml, чтобы настроить источник данных дозорного.
spring:
  cloud:
    sentinel:
      datasource:
        ds:
          nacos:
            server-addr: 10.0.10.48:8848
            data-id: ${spring.application.name}-sentinel
            group-id: DEFAULT_GROUP
            rule-type: flow

  • Создайте текущую конфигурацию ограничения в nacosaccount-service-sentinel(Формат конфигурации установлен в json)
[
    {
        "resource": "getByCode",
        "limitApp": "default",
        "grade": 1,
        "count": 3,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

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

resource: имя ресурса, то есть объект текущего правила ограничения

limitApp: источник вызова для управления потоком, если он установлен по умолчанию, источник вызова не будет различен.

grade: Тип порога ограничения тока (QPS или количество одновременных потоков); 0 означает ограничение тока в соответствии с количеством одновременных потоков, 1 означает управление потоком в соответствии с QPS.

count: порог ограничения тока

strategy: вызвать текущую стратегию ограничения отношения

controlBehavior: Эффект управления потоком (прямой отказ, разогрев, единая очередь)

clusterMode: находится ли он в режиме кластера

  • ВойтиsentinelПроверьте приборную панель и обнаружите, что Sentinel автоматически получает конфигурацию nacos.
    image.png
  • Часто обновляйте браузер, чтобы вызвать интерфейс, чтобы убедиться, что интерфейс обычно ограничен.

предохранитель

Концептуальная записка

потребительorder-serviceнужно сначала позвонитьproduct-serviceПолучите конкретный продукт, а затем обработайте другую бизнес-логику. но этоproduct-serviceИнтерфейс не очень стабилен и часто выдает исключения, либо реакция медленная, что приводит кorder-serviceреакция замедляется; если оставить в покое,order-serviceможет бытьproduct-serviceтянуть вниз. на этот раз для защитыorder-service, мы должныproduct-serviceИнтерфейс сдулся.

image.png

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

конфигурация автоматического выключателя

В Sentinel существует три стратегии перехода на более раннюю версию автоматического выключателя:

  • RT (среднее время ответа):
    Когда среднее время отклика ресурса превышает пороговое значение, ресурс переходит в квазидеградированное состояние. Далее, если 5 запросов продолжают поступать, и их RT продолжают превышать этот порог, то в течение следующего временного окна вызовы этого метода автоматически вызовут исключение DegradeException. Когда наступит следующее временное окно, будет введено еще 5 запросов, и вышеуказанное суждение будет повторено.
  • ненормальная пропорция
    Когда отношение общего количества исключений в секунду к пропускной способности ресурса превышает пороговое значение, ресурс переходит в деградированное состояние, то есть в течение следующего временного окна вызовы этого метода автоматически вызовут исключение DegradeException. Пороговый диапазон для отношения аномалий составляет [0,0, 1,0], что соответствует 0–100 %.
  • Количество исключений
    Когда количество аномальных ресурсов за последнюю минуту превышает пороговое значение, цепь разрывается.

Во-первых, мы трансформируем исходный интерфейс и позволяем ему бросать напрямуюRuntimeexception:

@GetMapping("/product/getByCode/{productCode}")
@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")
public ResultData<ProductDTO> getByCode(@PathVariable String productCode){
    log.info("get product detail,productCode is :{}",productCode);
    ProductDTO productDTO = productService.selectByCode(productCode);
    throw new RuntimeException("error");
//        return ResultData.success(productDTO);
}

Здесь мы будемproduct-serviceУстановите следующие правила автоматического выключателя:image.png

если/product/getByCodeЕсли частота исключений превышает 50 %, то в течение следующих 2 секунд сразу сработает понижение версии предохранителя, и будет сброшено значение по умолчанию.DegradeExceptionисключение, например:

2019-12-10 19:35:53,764 ERROR [dispatcherServlet]:175 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause
com.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null

пользовательское исключение

Исключение пользовательского предохранителя похоже на исключение текущего ограничения.Мы используем резервный атрибут, чтобы указать метод пользовательского исключения, например:

@SentinelResource(value = "/product/getByCode",fallback = "fallbackHandler")
public ResultData<ProductDTO> getByCode(@PathVariable String productCode){
 ...
}
/**
 * 自定义熔断异常
 * 返回值和参数要跟目标函数一样
 */
public ResultData<ProductDTO> fallbackHandler(String productCode){
    return ResultData.fail(800,"服务被熔断了,不要调用!");
}

Обратите внимание, что параметры и возвращаемые значения пользовательского метода исключения должны быть такими же, как у целевого метода.

Эффект следующий:image.png

постоянная конфигурация

  • представлятьsentinel-datasource-nacosкомпоненты, которые могут быть сконфигурированы как токоограничивающие
  • Измените application.yml, чтобы настроить источник данных дозорного.
spring:
  cloud:
    sentinel:
      datasource:
        ds:
          nacos:
            server-addr: 192.168.0.106:8848
            data-id: ${spring.application.name}-sentinel-degrade
            group-id: DEFAULT_GROUP
            rule-type: degrade

  • Создайте файл конфигурации в nacosproduct-service-sentinel-degrade, выполните следующую настройку
[
    {
    "resource": "/product/getByCode",
    "count": 0.5,
    "grade": 1,
    "passCount": 0,
    "timeWindow": 2
  }
]

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

resource: имя ресурса, который является объектом правила перехода на более раннюю версию.

count: порог

grade: Режим деградации 0: RT 1: Аномальное соотношение 2: Аномальное число

timeWindow: Окно времени (в секундах)

  • Войдите в sentinel, чтобы просмотреть панель инструментов, и обнаружил, что sentinel автоматически получает конфигурацию nacos.
    image.png

кровь и слезы

Если вы появились в процессе использования дозорногоFailed to fetch metric from Ошибка заключается в следующем:

Failed to fetch metric from <http://192.168.136.1:8719/metric?startTime=1563865044000&endTime=1563865050000&refetch=false>
 (ConnectionException: Connection refused: no further information)

В это время вам необходимо проверить список сервисов на дозорной консоли, чтобы убедиться, что он соответствует вашему IP-адресу. (Раньше я устанавливал виртуальную машину, и часовой перехватил мой виртуальный IP-адрес, я не знаю, почему...)image.png

Если вы обнаружите, что адрес прослушивания неверен, вы можете добавить конфигурацию IP-адреса клиента в конфигурацию клиента Sentinel.

spring:
  cloud:
    sentinel:
      transport:
        client-ip: 192.168.0.108

На данный момент мы добавили в наши микросервисы защиту от тока и предохранителей, поэтому нам больше не нужно беспокоиться о влиянии аномального трафика, а нестабильность нижестоящей системы делает наши собственные сервисы недоступными. Тогда этот выпуск «Практическая битва Spring Cloud Alibaba Microservices 5 — Current Limiting and Fusing» должен закончиться, и мы увидимся в следующем выпуске!image.png

Позвольте мне попросить еще одну волну внимания, прежде чем мы снова увидимся!
image.png

серия статей

Добро пожаловать, чтобы отсканировать код и подписаться на общедоступную учетную запись WeChat илиличный блог