
Библиотека отказоустойчивости для Java, предоставляющая circuit breaker, rate limiter, retry, bulkhead, timeout и декораторы кэша для функционального программирования.
= Библиотека отказоустойчивости, предназначенная для функционального программирования :author: Robert Winkler and Bohdan Storozhuk :icons: :toc: macro :numbered: 1 ifdef::env-github[] :tip-caption: 💡 :note-caption: ℹ️ :important-caption: ❗ :caution-caption: 🔥 :warning-caption: ⚠️ endif::[]
image:https://github.com/resilience4j/resilience4j/actions/workflows/gradle-build.yml/badge.svg["Build Status"] image:https://img.shields.io/nexus/r/io.github.resilience4j/resilience4j-circuitbreaker?server=https%3A%2F%2Foss.sonatype.org["Release"] image:https://img.shields.io/nexus/s/io.github.resilience4j/resilience4j-circuitbreaker?server=https%3A%2F%2Foss.sonatype.org["Snapshot"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"]
image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=coverage["Coverage", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=sqale_rating["Maintainability", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=reliability_rating["Reliability", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=security_rating["Security", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=vulnerabilities["Vulnerabilities", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"] image:https://sonarcloud.io/api/project_badges/measure?project=resilience4j_resilience4j&metric=bugs["Bugs", link="https://sonarcloud.io/dashboard?id=resilience4j_resilience4j"]
toc::[]
== Введение
Resilience4j — это легковесная библиотека для обеспечения отказоустойчивости, предназначенная для функционального программирования. Resilience4j предоставляет функции высшего порядка (декораторы) для расширения любого функционального интерфейса, лямбда-выражения или ссылки на метод с помощью Circuit Breaker, Rate Limiter, Retry или Bulkhead. Вы можете накладывать несколько декораторов на любой функциональный интерфейс, лямбда-выражение или ссылку на метод. Преимущество в том, что вы можете выбрать только те декораторы, которые вам нужны, и ничего больше.
Resilience4j 3 требует Java 21.
// Create a CircuitBreaker with default configuration CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendService");
// Create a Retry with default configuration // 3 retry attempts and a fixed time interval between retries of 500ms Retry retry = Retry.ofDefaults("backendService");
// Create a Bulkhead with default configuration Bulkhead bulkhead = Bulkhead.ofDefaults("backendService");
Supplier supplier = () -> backendService .doSomething(param1, param2);
// Decorate your call to backendService.doSomething() // with a Bulkhead, CircuitBreaker and Retry // **note: you will need the resilience4j-all dependency for this Supplier decoratedSupplier = Decorators.ofSupplier(supplier) .withCircuitBreaker(circuitBreaker) .withBulkhead(bulkhead) .withRetry(retry) .decorate();
// Execute the decorated supplier and recover from any exception String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get();
// When you don't want to decorate your lambda expression, // but just execute it and protect the call by a CircuitBreaker. String result = circuitBreaker .executeSupplier(backendService::doSomething);
// You can also run the supplier asynchronously in a ThreadPoolBulkhead ThreadPoolBulkhead threadPoolBulkhead = ThreadPoolBulkhead .ofDefaults("backendService");
// The Scheduler is needed to schedule a timeout on a non-blocking CompletableFuture ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3); TimeLimiter timeLimiter = TimeLimiter.of(Duration.ofSeconds(1));
NOTE: С Resilience4j вам не нужно действовать по принципу «всё или ничего» — вы можете https://mvnrepository.com/artifact/io.github.resilience4j[*выбрать то, что нужно*].
== Документация
Настройка и использование описаны в нашем https://resilience4j.readme.io/docs[Руководстве пользователя].
https://github.com/resilience4j-docs-ja/resilience4j-docs-ja[Неофициальный перевод на японский язык волонтёрами]
https://github.com/lmhmhl/Resilience4j-Guides-Chinese[Неофициальный перевод документации Resilience4j на китайский язык волонтёрами]
== Обзор
Resilience4j предоставляет несколько основных модулей:
Существуют также дополнительные модули для метрик, Feign, Kotlin, Spring, Ratpack, Vertx, RxJava2 и других.
NOTE: Полный список модулей приведён в нашем https://resilience4j.readme.io/docs#section-modularization[Руководстве пользователя].
TIP: Пакет основных модулей или билдер +Decorators+ см. в https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-all[resilience4j-all].
== Лучшие практики
=== Управление экземплярами: когда совместно использовать, а когда нет
Одно из самых важных понятий для новичков — понимать, когда создавать отдельные экземпляры, а когда совместно использовать экземпляры для разных удалённых сервисов или бэкендов.
==== Почему важны уникальные экземпляры
Создание отдельных экземпляров для каждого бэкенд-сервиса критически важно для:
==== Паттерны, зависящие от экземпляра, и паттерны, не зависящие от экземпляра
===== Паттерны, зависящие от экземпляра (НЕЛЬЗЯ совместно использовать)
Эти паттерны хранят состояние, специфичное для конкретного сервиса, и ДОЛЖНЫ иметь отдельные экземпляры:
// CORRECT: Separate CircuitBreaker for each service CircuitBreaker paymentServiceCB = CircuitBreaker.ofDefaults("paymentService"); CircuitBreaker inventoryServiceCB = CircuitBreaker.ofDefaults("inventoryService"); CircuitBreaker notificationServiceCB = CircuitBreaker.ofDefaults("notificationService");