Spring Boot 3 игнорирует @CircuitBreaker

Я изучаю микросервисы и пытаюсь реализовать шаблон автоматического выключателя в одном из моих микросервисов. Вначале я хотел выбрать библиотеку Netflix Hystrix, но после некоторого поиска в Google я обнаружил, что она устарела и больше не поддерживается Spring Boot (CMIIW). Поэтому я выбираю библиотеку Resillience4j.

У меня есть метод в одной из служб, который имитирует медленный запуск при случайном вызове (он работает 11 секунд). Поэтому я хочу, чтобы CircuitBreaker уничтожил медленно выполняемый вызов.

Дело в том, что когда я импортировал все необходимые зависимости, Spring Boot 3 просто игнорирует аннотацию @CircuitBreaker, которую я помещаю над целевым методом.

Я использую Spring Boot 3.3.2 и Spring Cloud 2023.0.1.

Вот зависимости, которые у меня есть в моем pom.xml

// another deps not connected with the problem

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

А вот метод медленного выполнения, который вызывается при достижении одной из конечных точек:

    private void randomlyRunLong() {
        Random rand = new Random();
        int randomNum = rand.nextInt((3 - 1) + 1) + 1;
        if (randomNum == 3) sleep();
    }

    private void sleep() {
        try {
            Thread.sleep(11000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @CircuitBreaker(name = "getLicenseByOrgCircuitBreaker")
    public List<License> getLicensesByOrg(String organizationId) {
        randomlyRunLong();

        return licenseRepository.findByOrganizationId(organizationId);
    }

Я также пробовал настроить автоматический выключатель через application.yaml, но эти настройки не приносят никакого эффекта:

resilience4j:
    circuitbreaker:
        configs:
            default:
                slow-call-duration-threshold: 10s
                failure-rate-threshold: 1
                slow-call-rate-threshold: 1

Вот скрин из Postman Ответ в Почтальоне
Как видно, перерыва в работе автоматического выключателя нет.

Буду признателен за любые идеи, поэтому если кто-то сможет помочь, буду благодарен.

UPD: Вот ответ от конечной точки /health после 3 вызовов долго выполняющегося метода: Ответ почтальона

(P.S. Английский не является моим родным языком, так что извините за возможные ошибки)

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

Berk Kurkcuoglu 20.07.2024 00:31

Я попытался поместить Sleep() непосредственно в метод службы, чтобы каждый вызов выполнялся в течение 11 секунд, но автоматический выключатель все равно не работает.

Дмитрий 20.07.2024 00:37

Вы должны предоставить более подробную информацию, как вы это тестируете, что вы на самом деле подразумеваете под словом «выключатель не работает»? Вы можете запросить текущий статус автоматического выключателя, вызвав «/actuator/health». Поделитесь, пожалуйста, результатами.

Berk Kurkcuoglu 20.07.2024 00:42

Хорошо. Говоря «автоматический выключатель не работает», я имею в виду, что ожидаю какого-то исключения (CallNotPermitedException, насколько я помню) в ответ на длительный вызов. Я добавил ответ из конечной точки /health на вопрос.

Дмитрий 20.07.2024 01:24

Похоже, проблема в моей конфигурации автоматического выключателя, поскольку он остается в ЗАКРЫТОМ состоянии.

Дмитрий 20.07.2024 01:26

@BerkKurkcuoglu Я добавил настройку минимального количества вызовов в свою конфигурацию, и теперь получаю желаемое исключение в консоли. В любом случае спасибо за вашу помощь!

Дмитрий 20.07.2024 01:28

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

Abra 20.07.2024 12:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, проблема была в моей невнимательности при написании конфигурации автоматического выключателя.

минимумNumberOfCalls — настраивает минимальное количество вызовов, которое необходимо (за период скользящего окна), прежде чем CircuitBreaker сможет рассчитать частоту ошибок или скорость медленных вызовов.

Я не указал этот параметр в файле application.yaml, поэтому он принял значение по умолчанию (100), поэтому автоматический выключатель не рассчитывал частоту ошибок или скорость медленных вызовов.

Когда я указал желаемое значение для этого параметра, все начало работать как Я ожидал.

Итак, мой совет всем: будьте осторожны при настройке параметров автоматического выключателя и прочтите официальную документацию

Другие вопросы по теме