本篇Demo在前面3篇Demo的基础上继续改造。
Spring Cloud 之 服务注册与发现 Eureka组件
Spring Cloud 之 负载均衡 Ribbon组件
Spring Cloud 之 声明式REST客户端 Feign组件
本实例GitHub地址:https://github.com/MistraR/springCloudApplication
微服务架构中,服务之间相互调用,关系错综复杂,当某个基础服务出现问题,网络原因或是其他原因,调用它的服务就可能出现线程阻塞,导致服务崩溃,引起雪崩效应。
Hystrix是Netflix公司的开源项目,提供熔断器功能,防止分布式系统中的连锁故障。
Hystrix核心:
改造这篇文章的工程:Spring Cloud 之 负载均衡 Ribbon组件
在原pom.xml文件中添加依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
在应用主类添加注解@EnableHystrix
@SpringBootApplication
//通过@EnableEurekaClient向服务中心注册
@EnableEurekaClient
//开启断路器
@EnableHystrix
@EnableDiscoveryClient
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
/**
* 向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
*/
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
改造HelloService
在helloService()方法上添加@HystrixCommand(fallbackMethod = “hiError”),这样该方法就开启了熔断器功能。
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
/**
* 该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法
* fallbackMethod的返回值和参数类型需要和被@HystrixCommand注解的方法完全一致。否则会在运行时抛出异常。
* @param name
* @return
*/
@HystrixCommand(fallbackMethod = "hiError")
public String helloService(String name) {
return restTemplate.getForObject("http://SERVICE-HELLO/hi?name=" + name, String.class);
}
/**
* 关闭SERVICE-HELLO,再访问hiService方法就会跳这个方法
* @param name
* @return
*/
public String hiError(String name) {
return "hi," + name + ",sorry,error!";
}
}
在熔断器打开的情况下访问helloService()方法就会执行hiError()方法的逻辑。
依次启动eureka-server,eureka-client,service-ribbon,访问:http://localhost:8004/hello/hi?name=mistra
顺利执行了helloService()方法的逻辑,浏览器输出“hi mistra,i am from port:8003”。
现在关闭eureka-client服务,访问:http://localhost:8004/hello/hi?name=mistra。浏览器输出“hi,mistra,sorry,error!”。执行了fallbackMethod 的逻辑。
通过快速失败,请求能够及时得到处理,线程不在阻塞。
改造这篇文章的工程:Spring Cloud 之 声明式REST客户端 Feign组件
查看Maven依赖可以发现Feign包中已经默认集成了Hystrix。
正常情况下是不需要再添加依赖的。但是今天我这里启动报了一个错误"Caused by: java.lang.NoClassDefFoundError: com/netflix/hystrix/contrib/javanica/aop/aspectj/HystrixC",我新增了下面这个依赖:
<dependency>
<groupId>com.netflix.hystrixgroupId>
<artifactId>hystrix-javanicaartifactId>
<version>1.5.12version>
dependency>
feign是默认关闭了Hystrix功能的,只需要在配置文件中打开就可以了。
修改application.yml,添加配置
feign:
hystrix:
enabled: true
工程结构:
新建ServiceHiHystric作为快速失败处理类,必须实现FeignService接口,并注入到Ioc容器。
@Component
public class ServiceHiHystric implements FeignService{
@Override
public String sayHiFromClientOne(String name) {
return "sorry " + name;
}
}
改造FeignService,添加快速失败处理逻辑类ServiceHiHystric
@Service
@FeignClient(value = "service-hello",fallback = ServiceHiHystric.class)
public interface FeignService {
@RequestMapping(value = "/hi",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
依次启动eureka-server,eureka-client,service-feign。
访问:http://localhost:8005/hi?name=mistra
浏览器正常输出:“hi mistra,i am from port:8003”
关闭eureka-client服务,再次访问
浏览器输出:“sorry mistra”
由此可见,当调用的服务不可用时,会进入到fallback的逻辑处理类,执行相应的逻辑。
(在上面service-feign工程的基础上修改)
顾名思义,就是对熔断器的运行状况和指标进行监控,提供图形化界面展示。下图来自官方文档文档地址:
在Hystix的基础上添加依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
在应用主类上添加注解:
如果使用的Spring boot 为 2.0 +,为了安全,默认 Actuator 只暴露了2个端点,heath 和 info。我们还要配置暴露所有端点,配置文件新增配置:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
浏览器访问:http://localhost:项目端口/hystrix
有3个输入框,在第一个填入http://localhost:项目端口/actuator/hystrix.stream,下面的延迟和标题随意。点击Monitor Stream连续监测
(在上面service-feign工程的基础上修改)
Hystrix Dashboard只是对单个model进行监控,程序有很多个model,Hystrix Turbine就是将每个服务Hystrix Dashboard数据进行了整合。将多个服务的Hystrix Dashboard数据放在一个页面展示,进行集中监控。Turbine是聚合多个服务,通过服务实例 id 聚合,所以要注册到 eureka-server 中,获取服务列表,用以聚合监控。
在原来的基础上引入依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-turbineartifactId>
dependency>
应用主类添加注解:@EnableTurbine
配置文件添加配置:参考文档
turbine:
# 配置 eureka-server 中的 serviceId 列表,指定要监控的服务
app-config: service-feign,service-ribbon
aggregator:
cluster-config: default
# 指定集群名称
cluster-name-expression: "'default'"
还是访问:http://localhost:项目端口/hystrix
填入:http://localhost:项目端口/turbine.stream
本实例GitHub地址:https://github.com/MistraR/springCloudApplication