Este guia aborda a configuração de um cluster Hystrix no Spring Cloud, a integração com o monitor Turbine e a desacoplamento de fallbacks usando Feign, além de ajustes de timeout em ambientes clusterizados.
Configuração do Cluster Hystrix
Para criar um cluster Hystrix, inicie um novo projeto Spring Boot denominado microservico-fornecedor-hystrix-1005. Adicione as seguintes dependências ao arquivo pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.exemplo</groupId>
<artifactId>projeto-spring-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>microservico-fornecedor-hystrix-1005</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
</project>
Configure múltiplos perfis no arquivo application.yml para instâncias em portas diferentes (1004, 1005, 1006), garantindo que o nome do serviço seja consistente. Exemplo para a porta 1005:
servidor:
porta: 1005
spring:
datasource:
tipo: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/teste?useUnicode=true&characterEncoding=utf8
usuario: raiz
senha: raiz
jpa:
hibernate:
ddl-auto: update
show-sql: true
aplicacao:
nome: microservico-aluno
perfis: fornecedor-hystrix-1005
eureka:
instancia:
nome-host: localhost
nome-app: microservico-aluno
id-instancia: microservico-aluno:1005
preferir-endereco-ip: true
cliente:
url-servico:
padrao: http://eureka2001.exemplo.com:2001/eureka/,http://eureka2002.exemplo.com:2002/eureka/,http://eureka2003.exemplo.com:2003/eureka/
hystrix:
comando:
padrao:
execucao:
isolamento:
thread:
tempo-espera-milissegundos: 1500
Na clasce principal do aplicativo, adicione anotações para ativar o Hystrix e o cliente Eureka:
package com.exemplo.microservicofornecedorhystrix1005;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableCircuitBreaker
@EntityScan("com.exemplo.*.*")
@EnableEurekaClient
@SpringBootApplication
public class AplicativoMicroservicoFornecedorHystrix1005 {
public static void main(String[] args) {
SpringApplication.run(AplicativoMicroservicoFornecedorHystrix1005.class, args);
}
}
Inicie três instâncias com perfis distintos para formar o cluster.
Monitoramento com Turbine
Para monitorar o cluster, crie um projeto separado chamado microservico-consumidor-turbine-91. Adicione as dependências:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
</dependencies>
Configure o arquivo application.yml para Turbine:
servidor:
porta: 91
eureka:
cliente:
url-servico:
padrao: http://eureka2001.exemplo.com:2001/eureka/,http://eureka2002.exemplo.com:2002/eureka/,http://eureka2003.exemplo.com:2003/eureka/
turbine:
app-config: microservico-aluno
nome-cluster-expressao: "'padrao'"
spring:
aplicacao:
nome: turbine
Adicione @EnableTurbine à classe principal:
package com.exemplo.microservicoconsumidorturbine91;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableTurbine
public class AplicativoMicroservicoConsumidorTurbine91 {
public static void main(String[] args) {
SpringApplication.run(AplicativoMicroservicoConsumidorTurbine91.class, args);
}
}
Inicie os serviços Eureka, os fornecedores Hystrix, o consumidor e o Turbine. Acesse http://localhost:91/turbine.stream para dados em tempo real e use o dashboard Hystrix em http://localhost:90/hystrix para monitoramanto.
Integração Feign com Hystrix para Desacoplamento
Para desacoplar a lógica de fallback, evite usar @HystrixCommand diretamente no código do serviço. Em vez disso, integre com Feign. No projeto microservico-comum, adicione uma interface ClienteAlunoServico com um método hystrix():
@FeignClient(value="MICROSERVICO-ALUNO", fallbackFactory=FabricaFallbackAluno.class)
public interface ClienteAlunoServico {
@GetMapping(value="/aluno/hystrix")
Map<String, Object> hystrix();
}
Crie uma classe FabricaFallbackAluno implementando FallbackFactory:
package com.exemplo.microservicofornecedorhystrix.servico;
import com.exemplo.microservicocomum.ClienteAlunoServico;
import feign.hystrix.FallbackFactory;
import java.util.HashMap;
import java.util.Map;
public class FabricaFallbackAluno implements FallbackFactory<ClienteAlunoServico> {
@Override
public ClienteAlunoServico create(Throwable causa) {
return new ClienteAlunoServico() {
@Override
public Map<String, Object> hystrix() {
Map<String, Object> mapa = new HashMap<>();
mapa.put("codigo", 500);
mapa.put("info", "Sistema ocupado, tente novamente mais tarde");
return mapa;
}
// Implementar outros métodos se necessário
};
}
}
Habilite Hystrix no Feign no arquivo application.yml do módulo comum:
feign:
hystrix:
enabled: true
No projeto consumidor Feign, adicione um controlador que chama o método hystrix() e anote a classe principal com @EnableFeignClients.
Ajustes de Timeout em Cluster
Em ambientes clusterizados, o timeout do Ribbon (usado pelo Feign) deve ser maior que o do Hystrix. No projeto consumidor Feign, configure:
hystrix:
comando:
padrao:
execucao:
isolamento:
thread:
tempo-espera-milissegundos: 1500
ribbon:
tempo-leitura: 10000
tempo-conexao: 9000
Isso garante que o timeout do Hystrix seja efetivo, já que o Ribbon tem um tempo padrão de 1 segundo.