Рубрики
Без рубрики

Отказоустойчивость микропрофиля について

В этом содержании объясняется обзор отказоустойчивости микропрофиля. Помеченный java, микропрофиль.

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

Отказоустойчивость Microprofile обеспечивает функциональность, необходимую для создания этих отказоустойчивых сервисов.Реализация проста в разработке на основе аннотаций CDI и работает на перехватчиках CDI (классы должны быть реализованы как компоненты CDI). Это позволяет отделить избыточный код для бизнес-логики и устранения неисправностей и упрощает его реализацию.

Политикой отказоустойчивости микропрофиля можно управлять вне внешних настроек, а конфигурация микропрофиля также может использоваться для управления политиками.

Основные характеристики, включенные в спецификацию отказоустойчивости

1. Тайм-аут: Используйте аннотацию @Timeout. Определяет максимальное время, необходимое для обработки
2. Повторите попытку: Используйте аннотацию @Retry. Задает поведение повторной попытки при сбое обработки
3. Запасной вариант: Используйте аннотацию @Запасной вариант. Предоставляет альтернативный метод (вызов другого метода) при сбое обработки
4. Переборка (переборка): Используйте аннотацию @Bulkhead.Ограничьте количество одновременных выполнений.Это снижает нагрузку на один процесс и снижает время отклика при больших нагрузках, предотвращая возникающие в результате этого цепные сбои во всей системе.
5. Автоматические выключатели: Используйте аннотацию @Circuitbreaker.Если процесс завершится повторным сбоем, вызов процесса автоматически завершится немедленно
6. Асинхронный: Используйте @Асинхронную аннотацию. Сделайте процесс асинхронным

В принципе, если вы хотите применить одну из вышеперечисленных политик (вы можете указать несколько), вы можете установить ее, просто добавив аннотацию к классу или методу, которые вы хотите реализовать.

Установив тайм-аут, вы можете запретить процессу продолжать ждать завершения процесса. Если вы не установите тайм・аут, сбой сети, высокая нагрузка на адресата и ответ не может быть возвращен немедленно, рабочие потоки в пуле соединений вызывающего абонента могут быть исчерпаны и т.д., И вызывающий абонент также может быть перегружен. Поэтому при внедрении нескольких микросервисов или при вызове внешних служб тайм-аут устанавливается в сотрудничестве между каждой службой.

@Timeout(400) // 接続タイムアウト値 400ms (0.4 sec)
public Connection getConnectionForServiceA() {
   Connection conn = connectionService();
   return conn;
}

Аннотация @Timeout может быть добавлена на уровне класса или метода.Если значение тайм-аута достигнуто, возникает исключение TimeoutException.

Если у вас произошел незначительный сбой в сети или вы не получили ответа от получателя, вы можете использовать аннотацию @Retry для повторной попытки обработки вызова.

В политике повторных попыток можно настроить следующее:

Максимальное количество повторных попыток Максимальные попытки:
Интервал повторных попыток задержка:
Единица измерения задержки Задержка соединения:
Максимальная продолжительность повторной попытки Максимальная продолжительность:
единица измерения продолжительности Длительность единицы измерения:
Случайное изменение задержки повтора (отклонение тактового сигнала по времени (или периоду)) дрожание:
блок дрожания jitterДелаюНить:
Указывает сбой (исключение, ошибку) для повторной попытки. Повторная попытка:
Указывает на невозможность прерывания (исключение, ошибка). Прервать:

Аннотация @Retry может быть добавлена на уровне класса или на уровне метода, и при добавлении в класс она применяется ко всем методам, присутствующим в классе.При добавлении в метод таргетируется только указанный метод.Если вы добавляете аннотацию к классу, а также добавляете ее в метод, вступают в силу настройки, указанные в методе.

  1. Если процесс завершается успешно, результат возвращается успешно.
  2. Если Aborton указывает созданное исключение, оно повторно отправляет созданное исключение
  3. Если вы укажете возникшее исключение в retryon, вызов метода будет повторен
  4. В противном случае он повторно отправляет возникшее исключение

Его также можно использовать с другими аннотациями отказоустойчивости.

    /**
     * serviceA() メソッド呼び出しで、例外が送出された場合に、
     * 例外が IOException でない場合は再試行します。
     */
    @Retry(retryOn = Exception.class, abortOn = IOException.class)
    public void invokeService() {
        callServiceA();
    }

    /**
     * 最大再試行回数は90、再試行を実行する最大期間は 1000 ミリ秒に設定
     * 再試行の最大期間に達すると、最大再試行回数に達していない場合でも、再試行は実行されない。
     */
    @Retry(maxRetries = 90, maxDuration= 1000)
    public void serviceB() {
        callServiceB();
    }

    /**
    * クロック周波数のズレ(jitter)を 400ms と仮定した場合、-400ms 〜 400ms つまり
    * 0 (delay - jitter) 〜 800ms (delay + jitter )の差で再試行が行われることが予想されます。
    * 最大遅延が発生した場合を想定し、3200/800=4 で、最低試行回数は4回以上、
    * 最大でも 10 回を超えない試行回数を設定します
    */
    @Retry(delay = 400, maxDuration= 3200, jitter= 400, maxRetries = 10)
    public Connection serviceA() {
        return getConnectionForServiceA();
    }

Аннотацию @Fallback можно указать на уровне метода.Если аннотированный метод завершается исключением, вызывается метод, указанный в резервном методе.

Аннотацию @Fallback можно использовать отдельно или с другими аннотациями отказоустойчивости. При использовании с другими аннотациями резервный вариант вызывается после выполнения всех других операций по отказоустойчивости.

Например, если определено значение @Retry, выполняется резервная операция, если повторная попытка превышает максимальное количество попыток. Кроме того, если @Circuitbreaker определен вместе, он будет немедленно вызван, если вызов метода завершится неудачей.И всякий раз, когда цепь разомкнута, вызывается запасной метод.

3.1 Пример реализации резервной обработки с помощью реализации резервного обработчика

Определяет класс резервного обработчика (serviceinvocationafallbackhandler), который реализует интерфейс резервного обработчика.Затем он реализует альтернативную обработку в методе дескриптора.

В этом случае вы можете использовать конфигурацию микропрофиля для создания приложения.serviceinvokeA.Он реализует свойство fallbackreplymessage или строку, определяемую переменными среды и т. Д. чтобы ответить.

@Dependent
public class ServiceInvocationAFallbackHandler implements FallbackHandler {

    @ConfigProperty(name="app.serviceinvokeA.FallbackReplyMessage", defaultValue = "Unconfigured Default Reply")
    private String replyString;

    @Override
    public String handle(ExecutionContext ec) {
        return replyString;
    }
}

Если вызывается метод businesslogicservicebean#invokeservicea(), здесь внутри будет вызвано исключение RuntimeException, но оно повторит обработку 3 раза, после того, как все попытки завершатся неудачей, будет вызван serviceinvocationafallbackhandler#handle().

@RequestScoped
public class BusinessLogicServiceBean {

    // FallbackHandler の実装クラスを指定し @Fallback アノテーションを付加
    // 最大のリトライ回数 (3回)を超えた場合、FallbackHandler の handle() メソッドが呼ばれる
    @Retry(maxRetries = 3)
    @Fallback(ServiceInvocationAFallbackHandler.class)
    public String invokeServiceA() {
        throw new RuntimeException("Connection failed");
        return null;
    }   
}

3.2 Пример реализации резервной обработки с помощью резервного метода

В аннотации @Запасной вариант напишите имя метода, который вы хотите вызвать в качестве альтернативы.

Здесь мы определяем метод fallbackforserviceb() в качестве альтернативного метода.

@RequestScoped
public class BusinessLogicServiceBean {

    @Retry(maxRetries = 3)
    @Fallback(fallbackMethod= "fallbackForServiceB")
    public String invokeServiceB() {
        counterForInvokingServiceB++;
       return nameService();
    }


    @ConfigProperty(name="app.serviceinvokeB.FallbackReplyMessage", defaultValue = "Unconfigured Default Reply")
    private String replyString;

    private String fallbackForInvokeServiceB() {
        return replyString;
    }

Шаблон переборки используется для предотвращения распространения некоторых системных сбоев по всей системе и вывода всей системы из строя.Реализация микропрофиля ограничивает количество одновременных запросов на доступ к экземпляру.

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

Аннотация @Bulkhead может быть добавлена на уровне класса или на уровне метода, и при добавлении в класс она применяется ко всем методам, присутствующим в классе.При добавлении в метод таргетируется только указанный метод.Если вы добавляете аннотацию к классу, а также добавляете ее в метод, вступают в силу настройки, указанные в методе.

Переборку можно установить следующими 2 способами.

  1. Изоляция пула потоков: Устанавливает максимальное количество одновременных запросов при размере очереди ожидания в пуле потоков (при использовании с аннотацией @Asynchronous).
  2. Изоляция семафора: допускается только установка количества одновременных запросов (если не используется с аннотацией @Asynchronous).

При использовании с аннотацией @Asynchronous применяется изоляция пула потоков.В приведенном ниже примере допускается до 5 одновременных запросов и 8 запросов хранятся в очереди ожидания.

// 最大5つの同時リクエストが許可され、最大 8つのリクエストが待機キューで許可される
@Asynchronous
@Bulkhead(value = 5, waitingTaskQueue = 8)
public Future invokeServiceA() {
   Connection conn = null;
   counterForInvokingServiceA++;
   conn = connectionService();
   return CompletableFuture.completedFuture(conn);
}

Если вы не используете аннотацию @Asynchronous, просто определите количество одновременных запросов.

@Bulkhead(5) // 最大5つの同時要求が許可されます
public Connection invokeServiceA() {
   Connection conn = null;
   counterForInvokingServiceA++;
   conn = connectionService();
   return conn;
}

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

Аннотация @Circuitbreaker может быть добавлена на уровне класса или метода, и при добавлении в класс она применяется ко всем методам, присутствующим в классе.При добавлении в метод таргетируется только указанный метод.Если вы добавляете аннотацию к классу, а также добавляете ее в метод, вступают в силу настройки, указанные в методе.

3 Состояния автоматического выключателя

Закрыто: (нормально)

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

Открыть: (в случае сбоя)

Если автоматический выключатель разомкнут, вызов службы, запущенной на автоматическом выключателе, немедленно завершится ошибкой с исключением circuitbreakeropenexception.Через некоторое время (настраивается) автоматический выключатель переходит в полуоткрытое состояние.

Полуоткрытый: (обзор аварийного восстановления)

В полуоткрытом состоянии начинаются попытки вызова службы (настраиваемый номер).Если какой-либо вызов завершается неудачей, автоматический выключатель снова возвращается в разомкнутое состояние.Если все попытки будут успешными, автоматический выключатель перейдет в замкнутое состояние.

Пример реализации автоматического выключателя 1

@CircuitBreaker(successThreshold = 10, requestVolumeThreshold = 4, failureRatio=0.5, delay = 1000)
public Connection serviceA() {
   Connection conn = null;
   counterForInvokingServiceA++;
   conn = connectionService();
   return conn;
}
Размер скользящего окна (количество знаменателей, используемых для расчета коэффициента неисправности) для использования, когда автоматический выключатель “закрыт” Требуемое значение порогового значения:
Коэффициент отказов в скользящем окне, чтобы автоматический выключатель “открылся” Устранение неисправностей:
Количество попыток перейти в режим “закрыто”, когда автоматический выключатель “полуоткрыт” Успешный рубеж:
Время держать автоматические выключатели “открытыми” Отложитьおよび отложить объединение:

В приведенном выше примере схема “разомкнется”, если во время 2 последовательных вызовов произойдет 4 сбоя (4 x 0,5), что соответствует количеству переходных окон, указанных в requestVolumeThreshold 。 Цепь остается “разомкнутой” в течение 1000 миллисекунд, а затем переходит в положение “полуоткрыта”. После 10 успешных “полуоткрытых” вызовов схема снова “замыкается”.

リクエスト1-成功
リクエスト2-失敗
リクエスト3-成功
リクエスト4-成功
リクエスト5-失敗
リクエスト6-CircuitBreakerOpenException

В случае вышеупомянутого запроса 4 из последних 2 запросов завершаются неудачей, а значение Failureratio достигает 0,5, поэтому схема “открыта” по “Запросу 5” и возникает исключение circuitbreakeropenexception.

Добавьте определения исключений, которые считаются успешными/неудачными

Параметры failon и skipon определяют, должен ли автоматический выключатель быть “разомкнут” или нет, и используются для определения того, какие исключения следует считать отказами.

@CircuitBreaker(successThreshold = 10, requestVolumeThreshold = 4, failureRatio=0.5, delay = 1000,failOn = {ExceptionA.class, ExceptionB.class}, skipOn = ExceptionBSub.class))
public Connection serviceA() {
   Connection conn = null;
   counterForInvokingServiceA++;
   conn = connectionService();
   return conn;
}

Если возникает исключение, указанное для Failon, оно считается сбоем. Если возникает исключение, указанное для Skipon, оно считается успешным

Основными особенностями отказоустойчивости являются Как описано в//Архитектура//, это функции, перечисленные выше 1-5.Таким образом, асинхронная обработка напрямую не связана с отказоустойчивостью.Однако асинхронная обработка очень важна в распределенной обработке, и, объединив ее с различными функциями отказоустойчивости, она была включена в спецификацию для более эффективной работы.

Источник цитаты: Архитектура

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

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

@Асинхронные аннотации могут быть добавлены на уровне класса или на уровне метода, и при добавлении к классу они применяются ко всем методам, присутствующим в классе.При добавлении в метод таргетируется только указанный метод.Если вы добавляете аннотацию к классу, а также добавляете ее в метод, вступают в силу настройки, указанные в методе.

Когда вызывается метод с аннотацией @Asynchronous, он немедленно возвращает этап будущего или завершения.Остальная часть тела метода обрабатывается в отдельном потоке.Возвращенный этап будущего или завершения не будет иметь правильного значения до тех пор, пока асинхронный процесс не будет завершен.Если во время обработки возникает исключение, этап “Будущее” или “Завершение” завершается этим исключением. Если процесс завершается успешно, этап будущего или завершения возвращает возвращаемое значение (которое само по себе является этапом будущего или завершения).

@Asynchronous
public CompletionStage  serviceA(){
   Connection conn = null;
   counterForInvokingServiceA ++;
   conn = connectionService();
   return CompletableFuture.completedFuture(conn);
}

В приведенном выше примере вызов метода ServiceA является асинхронным.Вызов ServiceA возвращает этап завершения, и выполнение тела метода выполняется в отдельном потоке.

Примечание://Если вы вызываете @Asynchronous из области запросов CDI, область запросов должна быть активна во время вызова асинхронного метода.Методы с аннотацией @Asynchronous вызываются в java.util.Он должен возвращать будущую стадию или стадию завершения параллельного пакета.Если нет, то будет вызвано исключение faulttolerancedefinitionexception.

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

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

///

Например, если вы хотите переопределить параметры, указанные в аннотации Тайм-аута или Повторной попытки, указанной в определенном методе извне, напишите следующее в конфигурации микропрофиля.

com.yoshio3.FaultToleranceService.resilient.ResilienceController/checkTimeout/Timeout/value=2000
com.yoshio3.FaultToleranceService.resilient.ResilienceController/checkTimeout/Retry/maxDuration=3000

Если вы хотите применить его ко всему классу, вы можете удалить часть имени метода и применить его ко всему классу, как показано ниже.

com.yoshio3.FaultToleranceService.resilient.ResilienceController/Timeout/value=2000
com.yoshio3.FaultToleranceService.resilient.ResilienceController/Retry/maxDuration=3000

И если вы хотите применить одно и то же правило ко всему коду в вашем проекте, вы также можете включить только аннотации и настройки параметров.

Timeout/value=2000
Retry/maxDuration=3000

Здесь мы рассмотрели код для создания приложения, которое использует отказоустойчивость микропрофиля для повышения отказоустойчивости.Следующая ошибка – это ошибка Я хотел бы на самом деле создать приложение, которое использует допуск и интегрирует несколько отказоустойчивых служб в Azure.

Оригинал: “https://dev.to/azure/microprofile-fault-tolerance-1a6g”