Como implementar padrões de resiliência em aplicativos Java usando Resilience4j

Por Gaspar Barancelli Junior em 17 de março de 2023

Quando se trata de construir sistemas distribuídos, a resiliência é fundamental para garantir a disponibilidade e a confiabilidade do serviço. O Resilience4j é uma biblioteca Java de código aberto que oferece uma maneira fácil de implementar padrões de resiliência, como circuit breakers, retries, ratelimits e bulkheads, em seus aplicativos. Projetado especificamente para arquiteturas de microserviços, o Resilience4j é uma biblioteca modular e flexível que permite escolher e implementar apenas os recursos de resiliência necessários em cada serviço. Com o Resilience4j, você pode construir aplicativos resilientes, capazes de lidar com falhas sem afetar a qualidade ou a disponibilidade do serviço.

Neste artigo, vamos explorar alguns dos recursos mais populares da Resilience4j e como configurá-los em seu aplicativo.

Configuração

Cada recurso do Resilience4j possui sua própria dependência. Isso ocorre porque o Resilience4j é modular, o que significa que você pode escolher quais recursos deseja usar em sua aplicação e incluir apenas as dependências necessárias.

Para os exemplos a seguir nesse post, utilizamos as seguintes dependências.

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-retry</artifactId>
    <version>2.0.2</version>
</dependency>

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-bulkhead</artifactId>
    <version>2.0.2</version>
</dependency>

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-circuitbreaker</artifactId>
    <version>2.0.2</version>
</dependency>

Retry

O recurso de retry é útil quando um serviço dependente não está disponível temporariamente. Por exemplo, se um serviço está em manutenção ou sobrecarregado, você pode configurar a biblioteca para tentar novamente a chamada após um determinado intervalo.

Para configurar o recurso de retry, você pode usar o seguinte código:

RetryConfig config = RetryConfig.custom()
    .maxAttempts(3)
    .waitDuration(Duration.ofMillis(500))
    .build();
Retry retry = Retry.of("meu-retry", config);

Este código configura a biblioteca para tentar a chamada três vezes, com um intervalo de 500 milissegundos entre cada tentativa.

Bulkhead

O recurso de bulkhead é útil para isolar a falha de uma parte do sistema, garantindo que outras partes do sistema ainda funcionem corretamente. Por exemplo, se um serviço dependente está sobrecarregado e não pode lidar com novas solicitações, você pode configurar o recurso de bulkhead para limitar o número de solicitações que podem ser processadas por vez.

Para configurar o recurso de bulkhead, você pode usar o seguinte código:

ThreadPoolBulkheadConfig config = ThreadPoolBulkheadConfig.custom()
    .maxThreadPoolSize(10)
    .coreThreadPoolSize(2)
    .queueCapacity(20)
    .build();
ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.of("meu-bulkhead", config);

Este código configura a biblioteca para limitar o número de solicitações que podem ser processadas ao mesmo tempo em 10 e definir um tamanho de fila de 20.

Circuit Breaker

O recurso de circuit breaker é útil para evitar chamadas repetidas a um serviço que falhou. Ele funciona monitorando as chamadas ao serviço e, quando o número de falhas excede um determinado limite, a biblioteca ativa o circuit breaker, impedindo temporariamente chamadas adicionais ao serviço. Isso ajuda a evitar sobrecarga do serviço e a reduzir o tempo de resposta do aplicativo.

Para configurar o recurso de circuit breaker, você pode usar o seguinte código:

CircuitBreakerConfig config = CircuitBreakerConfig.custom()
    .failureRateThreshold(50)
    .waitDurationInOpenState(Duration.ofMillis(1000))
    .build();
CircuitBreaker circuitBreaker = CircuitBreaker.of("meu-circuit-breaker", config);

Este código configura a biblioteca para ativar o circuit breaker quando a taxa de falha excede 50% e aguarda 1 segundo antes de tentar novamente a chamada.

Conclusão

Resilience4j é uma biblioteca poderosa que oferece vários recursos para ajudar a melhorar a resiliência de seus aplicativos Java. Neste artigo, discutimos alguns dos recursos mais populares, como retry, bulkhead e circuit breaker, e fornecemos exemplos de configuração para cada um deles. Ao implementar esses padrões de resiliência em seus aplicativos, você pode garantir que eles permaneçam disponíveis e confiáveis, mesmo quando enfrentam falhas em serviços dependentes ou interrupções na rede. Além disso, a modularidade da biblioteca permite que você escolha apenas os recursos necessários para cada serviço, o que ajuda a manter o tamanho do código e o desempenho geral do aplicativo. Em resumo, o Resilience4j é uma excelente escolha para desenvolvedores que procuram uma maneira fácil e flexível de melhorar a resiliência de seus aplicativos Java.

// Livros recomendados relacionados ao assunto do post

// Compartilhe esse Post