
Se você está desenvolvendo um microserviço com Spring Boot e precisa se comunicar com outros serviços via HTTP, o OpenFeign é uma excelente escolha. Ele simplifica a criação de clientes HTTP declarativos. Além disso, quando estamos lidando com comunicação entre serviços, é essencial implementar padrões de tolerância a falhas, como o Circuit Breaker. Para isso, o Resilience4J é uma biblioteca robusta que pode ser facilmente integrada ao Spring Boot.
Neste post, vamos configurar e utilizar o OpenFeign e o Circuit Breaker do Resilience4J em um projeto Spring Boot com Gradle, utilizando Java 21. Também veremos por que é vantajoso usar Gradle com Kotlin ao invés de Groovy.
O que é um circuit breaker?
Um circuit breaker é essencial em comunicações síncronas REST para garantir a resiliência e robustez do sistema. Ele monitora interações entre componentes e bloqueia temporariamente solicitações a serviços com falhas ou alta latência, prevenindo sobrecargas e falhas em cascata. Isso permite que o sistema continue operando, melhora a latência percebida pelo usuário e fornece visibilidade sobre a saúde dos serviços. Além disso, o circuit breaker testa periodicamente os serviços problemáticos, reativando-os quando voltam a funcionar corretamente, o que garante uma recuperação controlada e eficiente. Possui também um esquema de fallback, que permite tratar APIs problemáticas.
Configuração do Projeto
- Inicializando o Projeto Spring Boot: Para começar, vamos criar um novo projeto Spring Boot. Você pode usar o Spring Initializr (https://start.spring.io/) para gerar um esqueleto de projeto com as dependências básicas. Selecione as seguintes dependências:
- Spring Web
- Spring Cloud OpenFeign
- Spring Cloud Starter Circuit Breaker Resilience4J
- Como estamos utilizando Gradle, certifique-se de escolher esta opção no Initializr.
- Configuração do Gradle com Kotlin DSL: No arquivo
build.gradle.kts(Gradle Kotlin DSL), adicione as seguintes dependências:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign
implementation("org.springframework.cloud:spring-cloud-starter-openfeign:4.1.1")
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-circuitbreaker-resilience4j
implementation("org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j:3.1.1")
}
Configurando OpenFeign
- Habilitando o OpenFeign no Spring Boot: No arquivo principal da aplicação (Application.java), habilite o Feign adicionando a anotação
@EnableFeignClients. - Criando um Cliente Feign: Crie uma interface Feign para definir o cliente HTTP. Por exemplo:
@FeignClient(name = "metMuseumClient", url = "https://collection.metmuseum.org/public/collection/v1")
public interface MetMuseumClient {
@GetMapping("/objects/{object_id}")
ObjectResponse getObject(@PathVariable("object_id")int objectId);
}
Configurando o Circuit Breaker com Resilience4J
- Habilitando o Circuit Breaker no Feign: Configure o Feign para utilizar o Circuit Breaker do Resilience4J. Adicione as configurações no arquivo
application.yml. - Configurando o Feign com Circuit Breaker: Adicione a configuração para habilitar o Resilience4J Circuit Breaker nas chamadas Feign. Crie um configurador Feign na sua aplicação:
Criando uma Classe Service
@Service
@RequiredArgsConstructor
public class ArtObjectService {
private final MetMuseumClient metMuseumClient;
public ObjectResponse getObject(int objectId) {
return metMuseumClient.getObject(objectId);
}
}
Criando um RestController para Acionar o Cliente Feign
Para expor um endpoint REST que utilize o serviço criado, crie um controlador REST. Este controlador chamará o serviço que, por sua vez, utilizará o cliente Feign para obter os dados dos objetos do met museum.
@RestController
@RequestMapping("/met")
@RequiredArgsConstructor
public class ObjectController {
private final ArtObjectService artObjectService;
@GetMapping("/object/{object_id}")
public ResponseEntity getObject(@PathVariable("object_id") int objectId){
return ResponseEntity.ok(artObjectService.getObject(objectId));
}
}
Criando as configurações do Cliente Feign
spring:
cloud:
circuitbreaker:
resilience4j:
enabled: true
openfeign:
circuitbreaker:
enabled: true
alphanumeric-ids:
enabled: true
client:
config:
default:
loggerlevel: full
connectTimeout: 1000
readTimeout: 1000
resilience4j:
circuitbreaker:
configs:
default:
registerHealthIndicator: true
slidingWindowSize: 50 #como é baseado em tempo, ficará 50 segundos em monitoramento
permittedNumberOfCallsInHalfOpenState: 3
slidingWindowType: TIME_BASED #janela a ser monitorada
minimumNumberOfCalls: 5
waitDurationInOpenState: 500s
failureRateThreshold: 3
eventConsumerBufferSize: 10
Por que usar Gradle com Kotlin DSL ao invés de Groovy DSL
- Sintaxe Melhorada e Tipagem Estática: A sintaxe do Kotlin DSL é mais concisa e oferece tipagem estática, o que ajuda a detectar erros em tempo de compilação. Isso torna o processo de desenvolvimento mais seguro e reduz a probabilidade de erros em tempo de execução.
- Melhor Integração com IDEs: As IDEs, especialmente o IntelliJ IDEA, oferecem suporte superior para Kotlin DSL em comparação com Groovy DSL. A autocompletação, navegação de código e refatoração são mais eficientes e confiáveis, proporcionando uma melhor experiência de desenvolvimento.
- Consistência no Ecossistema Kotlin: Para equipes que já estão usando Kotlin em seus projetos, utilizar o Kotlin DSL para Gradle traz consistência no ecossistema de desenvolvimento. Isso facilita a curva de aprendizado e promove a reutilização de conhecimentos e práticas.
- Recursos Modernos do Kotlin: O Kotlin DSL aproveita recursos modernos do Kotlin, como lambdas, extensões de função e outras características avançadas, que permitem escrever scripts de build mais poderosos e expressivos.
- Manutenção a Longo Prazo: Gradle está investindo continuamente no Kotlin DSL, o que indica um forte suporte e melhorias futuras. Adotar o Kotlin DSL pode ser uma escolha estratégica para a manutenção e evolução a longo prazo dos scripts de build.
Conclusão
Configurar OpenFeign e o Circuit Breaker do Resilience4J em um projeto Spring Boot com Gradle e Java 21 é uma abordagem moderna e eficiente para criar microserviços resilientes. Usar Gradle com Kotlin DSL oferece várias vantagens sobre o Groovy, incluindo melhor suporte de IDE, tipagem estática e uma sintaxe mais clara e concisa. Experimente esta configuração em seu próximo projeto e veja como ela funciona.
Viu algum erro, tem alguma sugestão? Comenta aí.
Quer ver o código na íntegra? https://github.com/nathalia-amarals/openfeignresilienceconfig
Bibliografia:
- https://spring.io/projects/spring-cloud-circuitbreaker
- https://www.baeldung.com/spring-boot-resilience4j
- https://docs.spring.io/spring-cloud-circuitbreaker/docs/current/reference/html/spring-cloud-circuitbreaker-resilience4j.html
- https://mixedanalytics.com/blog/list-actually-free-open-no-auth-needed-apis/
- https://metmuseum.github.io/
- https://docs.gradle.org/current/userguide/part1_gradle_init.html
- https://medium.com/bliblidotcom-techblog/spring-cloud-circuit-breaker-implementation-using-resilience4j-and-spring-open-feign-734d0fd34e37
- https://medium.com/bliblidotcom-techblog/spring-cloud-circuit-breaker-implementation-using-resilience4j-and-reactive-feign-24a863e98457
- https://github.com/spring-cloud/spring-cloud-release/issues/261
- https://cloud.spring.io/spring-cloud-stream-binder-kafka/spring-cloud-stream-binder-kafka.html#_appendices