Введение: эта статья является пятой статьей в серии статей о борьбе с микросервисами 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 запросов в секунду, извините, я просто выброшу и не буду обрабатывать, а потом выкину исключение потребителю, пытающемуся меня утащить вниз , хм, никак! .
В целом, текущее ограничение предназначено для защиты собственной системы путем ограничения вызовов вызывающего абонента самому себе.
Конфигурация ограничения тока
Идеал пухленький, реальность худенькая. Поскольку я не очень хорошо разбираюсь в инструментах стресс-тестирования, таких как Jmeter, для удобства тестирования мы будемaccout-service
Пороговое значение количества запросов в секунду для одной машины установлено равным 5. Если количество запросов в секунду превышает 5, оно будет напрямую отброшено.
Имя ресурса здесь то, что мы используем@SentinelResource
Аннотируйте пользовательские ресурсы.
Откройте браузер, быстро обновите браузер, когда запрос книг в секунду превысит 5, вы увидите следующую ошибку:
В журнале серверной службы вы увидите следующий журнал ошибок:
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.
Эффект следующий:
Гораздо элегантнее, чем предыдущая страница с ошибкой!
постоянная конфигурация
потому что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
- Создайте текущую конфигурацию ограничения в nacos
account-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. - Часто обновляйте браузер, чтобы вызвать интерфейс, чтобы убедиться, что интерфейс обычно ограничен.
предохранитель
Концептуальная записка
потребительorder-service
нужно сначала позвонитьproduct-service
Получите конкретный продукт, а затем обработайте другую бизнес-логику. но этоproduct-service
Интерфейс не очень стабилен и часто выдает исключения, либо реакция медленная, что приводит кorder-service
реакция замедляется; если оставить в покое,order-service
может бытьproduct-service
тянуть вниз. на этот раз для защитыorder-service
, мы должныproduct-service
Интерфейс сдулся.
В двух словах: автоматический выключатель экономит время отклика и поддерживает стабильность соединения, ограничивая свои обращения к внешним системам.
конфигурация автоматического выключателя
В 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
Установите следующие правила автоматического выключателя:
если/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,"服务被熔断了,不要调用!");
}
Обратите внимание, что параметры и возвращаемые значения пользовательского метода исключения должны быть такими же, как у целевого метода.
Эффект следующий:
постоянная конфигурация
- представлять
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
- Создайте файл конфигурации в nacos
product-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.
кровь и слезы
Если вы появились в процессе использования дозорного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-адрес, я не знаю, почему...)
Если вы обнаружите, что адрес прослушивания неверен, вы можете добавить конфигурацию IP-адреса клиента в конфигурацию клиента Sentinel.
spring:
cloud:
sentinel:
transport:
client-ip: 192.168.0.108
На данный момент мы добавили в наши микросервисы защиту от тока и предохранителей, поэтому нам больше не нужно беспокоиться о влиянии аномального трафика, а нестабильность нижестоящей системы делает наши собственные сервисы недоступными. Тогда этот выпуск «Практическая битва Spring Cloud Alibaba Microservices 5 — Current Limiting and Fusing» должен закончиться, и мы увидимся в следующем выпуске!
Позвольте мне попросить еще одну волну внимания, прежде чем мы снова увидимся!
серия статей
- SpringCloud Alibaba Microservices Практика 1 — Базовая подготовка среды
- SpringCloud Alibaba Microservices Practice II — Регистрация службы
- SpringCloud Alibaba Microservices Практика 3 — Звонок в службу поддержки
- SpringCloud Alibaba Microservices Practice 4 — Управление версиями
Добро пожаловать, чтобы отсканировать код и подписаться на общедоступную учетную запись WeChat илиличный блог