в предыдущем«Использование Sentinel для реализации ограничения тока интерфейса»В этой статье мы полагаемся только на интеграцию и инкапсуляцию Sentinel, представляя Spring Cloud Alibaba.spring-cloud-starter-alibaba-sentinel
, который завершает текущий контроль ограничения всех интерфейсов Spring MVC. Однако в практических приложениях нам может понадобиться ограничить уровень тока не ограниченным интерфейсом. Может быть желательно контролировать вызов метода и вызов внешнего ресурса. Ну, в настоящее время мы должны вручную определить точки ресурсов, которые необходимо ограничить, и настроить соответствующие текущие политики ограничения и другое содержимое.
Сегодня мы вместе научимся пользоваться@SentinelResource
Аннотации гибко определяют ресурсы управления и способы настройки стратегий управления.
пользовательская ресурсная точка
Следующие примеры основаны на том факте, что вы уже представили Spring Cloud Alibaba Sentinel.Если вы еще этого не знаете, рекомендуется сначала прочитать их.«Использование Sentinel для реализации ограничения тока интерфейса».
Шаг 1: Добавьте конфигурацию поддержки аннотаций в основной класс приложения:
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
// 注解支持的配置Bean
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
Шаг 2: Используйте там, где вам нужно контролировать трафик через Sentinel@SentinelResource
Аннотация, такая как следующая, для управления методом уровня логики службы в качестве примера:
@Slf4j
@Service
public class TestService {
@SentinelResource(value = "doSomeThing")
public void doSomeThing(String str) {
log.info(str);
}
}
На этом этапе определяется метод, который необходимо защитить. Поговорим о том, как реализовать различные стратегии защиты после определения ресурсных точек, в том числе: текущий лимит, даунгрейд и т. д.
Как реализовать ограничение тока и деградацию предохранителей
После определения точек ресурсов мы можем использовать панель инструментов, чтобы установить текущие ограничения и политики перехода на более ранние версии для защиты точек ресурсов. В то же время также возможно@SentinelResource
чтобы указать стратегию обработки исключений при возникновении текущего ограничения и перехода на более раннюю версию. Далее давайте посмотрим, как реализовано ограничение тока и переход на более раннюю версию.
Реализовать контроль ограничения тока
Шаг 1. Вызовите этот защищенный метод на веб-уровне:
@RestController
public class TestController {
@Autowired
private TestService testService;
@GetMapping("/hello")
public String hello() {
estService.doSomeThing("hello " + new Date());
return "didispace.com";
}
}
Шаг 2: Запустите тестовое приложение и запустите Sentinel-Dashboard. отправить запрос на/hello
В интерфейсе вы можете увидеть несколько контрольных точек, показанных ниже на Sentinel-Dashboard:
Как видите, в дополнение к предыдущему примеру записи есть/hello
Помимо ресурсной точки, есть еще однаdoSomeThing
ресурсная точка. Вы можете установить текущее правило ограничения для этой ресурсной точки через интерфейс, например, установить ее QPS на 2. так как/hello
Ресурс не имеет текущих ограничивающих правил, поэтому до тех пор, пока запрос/hello
интерфейс, вы можете напрямую имитировать вызовdoSomeThing
ресурсы, чтобы наблюдать, вступают ли в силу текущие правила ограничения.
Следующее может быть вызвано любым инструментом, который вам нравится/hello
Для интерфейса, если количество запросов в секунду превышает 2, появится следующая ошибка, указывающая, что текущая политика ограничения вступает в силу.
В это время консоль сервера также будет иметь соответствующий журнал ошибок ограничения тока:
2019-06-27 11:30:43.514 INFO 36898 --- [nio-8001-exec-3] c.d.a.sentinel.service.TestService : aaa
2019-06-27 11:30:43.905 ERROR 36898 --- [nio-8001-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : 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
Реализовать обработку исключений с ограничением тока
По умолчанию ограничивающая ток обработка управляющих ресурсов Sentinel напрямую выдает исключение, которое является содержимым журнала, опубликованным в предыдущем разделе. Это можно сделать, когда нет разумных деловых обязательств или интерфейсной стыковки.Однако в нормальных условиях для улучшения обслуживания пользователей после ограничения тока будет реализована некоторая специальная обработка.Мы не хотим показывать тупой отчет об ошибке . Затем просто выполните некоторую обработку на основе приведенного выше примера, например:
@Slf4j
@Service
public class TestService {
@SentinelResource(value = "doSomeThing", blockHandler = "exceptionHandler")
public void doSomeThing(String str) {
log.info(str);
}
// 限流与阻塞处理
public void exceptionHandler(String str, BlockException ex) {
log.error( "blockHandler:" + str, ex);
}
}
Делайте в основном две вещи:
- пройти через
@SentinelResource
аннотированныйblockHandler
Атрибуты формулируют конкретные функции обработки - Реализовать функцию обработки, параметры функции должны быть такими же, как параметры ресурсной точки, и добавить в конце
BlockException
Параметры исключения, при этом тип возвращаемого значения должен быть одинаковым.
Читатели, знакомые с Hystrix, обнаружат, что этот дизайн очень похож на определение отката в HystrixCommand, и его легко понять.
После выполнения вышеуказанных изменений попробуйте снова получить доступ к интерфейсу (обратите внимание, что текущие правила ограничения должны быть настроены), тогда внешний интерфейс не будет возвращать информацию об исключении, а задний конец будет печататьexceptionHandler
Вывод журнала, определенный в . В практических приложениях, пока текущий запрос на ограничение кэшируется или запросы внешнего интерфейса выполняются в соответствии с потребностями бизнеса, его можно реализовать на основе этого метода.
Понижение предохранителя
@SentinelResource
Обратите внимание, что помимо того, что он используется для управления ограничением тока, он также может реализовывать стратегию понижения рейтинга автоматических выключателей, аналогичную Hystrix. Давайте посмотрим, как его использовать.
Шаг 1: Как и в случае управления ограничением тока, используйте@SentinelResource
Аннотации отмечают ресурсные точки, такие как:
@Slf4j
@Service
public class TestService {
@SentinelResource(value = "doSomeThing2")
public void doSomeThing2(String str) {
log.info(str);
throw new RuntimeException("发生异常");
}
}
здесь, вTestService
Создайте новый метод в классе и используйте@SentinelResource
Назовите ресурс какdoSomeThing2
. Этот метод выдает исключение для совместной работы с последующей формулировкой стратегии перехода на более раннюю версию на основе доли исключений (аналогично Hystrix). Sentinel богаче, чем Hystrix, и имеет стратегию деградации, основанную на времени отклика и количестве исключений.
Шаг второй: В веб-слое вызывается этот защищенный метод:
@RestController
public class TestController {
@Autowired
private TestService testService;
@GetMapping("/hello2")
public String hello2() {
testService.doSomeThing2("hello2 " + new Date());
return "didispace.com";
}
}
Шаг 3: Запустите тестовое приложение и запустите Sentinel-Dashboard. отправить запрос на/hello2
интерфейс, так что Sentinel-Dashboard может видеть имяdoSomeThing2
ресурсная точка. Затем нажмите кнопку перехода на более раннюю версию, чтобы установить правила перехода на более раннюю версию для ресурса. Здесь используется стратегия соотношения аномалий, соотношение установлено на 0,5 (т.е.: 50% аномалий), а временное окно установлено на 2 (секунды).
Шаг 4: Проверьте переход на более раннюю версию предохранителя в соответствии с приведенной выше конфигурацией политики понижения версии, когдаdoSomeThing2
QPS вызова метода составляет >= 5. Если частота исключений превышает 50%, последующий вызов в течение 2 секунд напрямую вызовет предохранитель и переход на более раннюю версию, а значение по умолчанию будет выбрано напрямую.DegradeException
исключения, такие как:
2019-06-27 17:49:58.913 ERROR 99863 --- [nio-8001-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : 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
Объединенная обработка понижения
Определение обработки автоматических выключателей на более ранней версии в Sentinel очень просто, очень похоже на Hystrix. просто используйте@SentinelResource
аннотированныйfallback
атрибут для указания конкретного имени метода. Также необходимо отметить, что участие и отдача должны быть последовательными. Например:
@Slf4j
@Service
public class TestService {
// 熔断与降级处理
@SentinelResource(value = "doSomeThing2", fallback = "fallbackHandler")
public void doSomeThing2(String str) {
log.info(str);
throw new RuntimeException("发生异常");
}
public void fallbackHandler(String str) {
log.error("fallbackHandler:" + str);
}
}
После завершения вышеуказанного преобразования перезапустите приложение и установитеdoSomeThing2
Стратегия понижения уровня автоматического выключателя для ресурсов (с использованием процента исключений), затем частые запросы/hello2
интерфейс. После QPS>=5, поскольку этот интерфейс выдавал исключения, должно быть выполнено условие перехода на более раннюю версию предохранителя, и оно будет выполнено в это время.fallbackHandler
Метод, постоянно печатающий следующим образом:
2019-06-27 23:44:19.432 ERROR 58471 --- [nio-8001-exec-1] c.d.a.sentinel.service.TestService : fallbackHandler:hello2 Thu Jun 27 23:44:19 CST 2019
2019-06-27 23:44:19.599 ERROR 58471 --- [nio-8001-exec-2] c.d.a.sentinel.service.TestService : fallbackHandler:hello2 Thu Jun 27 23:44:19 CST 2019
2019-06-27 23:44:19.791 ERROR 58471 --- [nio-8001-exec-3] c.d.a.sentinel.service.TestService : fallbackHandler:hello2 Thu Jun 27 23:44:19 CST 2019
2019-06-27 23:44:19.975 ERROR 58471 --- [nio-8001-exec-4] c.d.a.sentinel.service.TestService : fallbackHandler:hello2 Thu Jun 27 23:44:19 CST 2019
2019-06-27 23:44:20.168 ERROR 58471 --- [nio-8001-exec-5] c.d.a.sentinel.service.TestService : fallbackHandler:hello2 Thu Jun 27 23:44:20 CST 2019
Дополнительные описания атрибутов аннотаций
о@SentinelResource
Были введены два основных использования аннотаций: конкретные случаи использования контроля ограничения тока и деградации предохранителей. Кроме того, эта аннотация имеет некоторые другие более точные настройки, такие как игнорирование некоторых конфигураций исключений, функции понижения версии по умолчанию и т. д., которые можно увидеть в следующих инструкциях:
-
value
: имя ресурса, обязательное (не может быть пустым) -
entryType
: тип записи, необязательный (по умолчаниюEntryType.OUT
) -
blockHandler
/blockHandlerClass
:blockHandler
Обработка корреспонденцииBlockException
Имя функции, необязательно. Область доступа к функции blockHandler должна бытьpublic
, тип возвращаемого значения должен соответствовать исходному методу, тип параметра должен соответствовать исходному методу, а в конце добавляется дополнительный параметр, типBlockException
. Функция blockHandler должна быть в том же классе, что и исходный метод по умолчанию. Если вы хотите использовать функции других классов, вы можете указатьblockHandlerClass
для соответствующего классаClass
Объект, обратите внимание, что соответствующая функция должна быть статической функцией, иначе она не может быть разрешена. -
fallback
: Имя резервной функции, необязательная, используемая для обеспечения логики резервной обработки при возникновении исключения. Резервную функцию можно использовать для всех типов исключений (кромеexceptionsToIgnore
Наизнанку вынуть необычный вид) для обработки. Требования к сигнатуре и расположению резервной функции:- Тип возвращаемого значения должен совпадать с типом возвращаемого значения исходной функции;
- Список параметров метода должен быть таким же, как и исходная функция, или вы можете добавить еще один
Throwable
Параметр типа используется для получения соответствующего исключения. - Резервная функция должна быть в том же классе, что и исходный метод по умолчанию. Если вы хотите использовать функции других классов, вы можете указать
fallbackClass
для соответствующего классаClass
Объект, обратите внимание, что соответствующая функция должна быть статической функцией, иначе она не может быть разрешена.
-
defaultFallback
(начиная с версии 1.6.0): Имя резервной функции по умолчанию, необязательное, обычно используется для общей логики резервного копирования (т. е. может использоваться для многих служб или методов). Резервную функцию по умолчанию можно использовать для всех типов исключений (кромеexceptionsToIgnore
Исключенные в нем типы исключений) обрабатываются. Если настроены и резервный вариант, и defaultFallback, вступит в силу только резервный вариант. Сигнатура функции defaultFallback требует:- Тип возвращаемого значения должен совпадать с типом возвращаемого значения исходной функции;
- Список параметров метода должен быть пустым, либо может быть дополнительный
Throwable
Параметр типа используется для получения соответствующего исключения. - Функция defaultFallback по умолчанию должна находиться в том же классе, что и исходный метод. Если вы хотите использовать функции других классов, вы можете указать
fallbackClass
для соответствующего классаClass
Объект, обратите внимание, что соответствующая функция должна быть статической функцией, иначе она не может быть разрешена.
-
exceptionsToIgnore
(начиная с версии 1.6.0): используется для указания исключений, которые не будут учитываться в статистике исключений и не попадут в резервную логику, а будут выброшены как есть.
Примечание. Резервная функция в версиях до 1.6.0 предназначена только для исключений перехода на более раннюю версию (
DegradeException
) обрабатывать,Не удается обработать бизнес-исключения.
В частности, если сконфигурированы и blockHandler, и резервный вариант, они будут деградированы из-за ограничения тока и выброшены.BlockException
войдет толькоblockHandler
логика обработки. Если не настроенblockHandler
,fallback
иdefaultFallback
, когда текущий предел понижен,BlockException
бросить прямо.
использованная литература:Официальная документация Sentinel
Выходные данные: эта статья основана на версии 0.2.2 spring-cloud-alibaba-dependencies.Если у вас возникнут особые проблемы, проверьте, согласуются ли версии, или непосредственно обратитесь к примерам кода, чтобы проверить конкретные случаи.
пример кода
Клиентский код контента, представленный в этой статье, читатели примера могут проверить код на следующем складе.alibaba-sentinel-annotation
проект:
- Гитхаб:GitHub.com/first87112/sp…
- Гостиница:git ee.com/brother space/S…
Если вы заинтересованы в них, добро пожаловать, пометьте, подпишитесь, добавьте в избранное и вперед, чтобы поддержать!