本文我们来演示下Hystrix中解决雪崩效应的第一种方式降级的实现

1.场景介绍

先来看下正常服务调用的情况
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_客户端
当consumer调用provider服务出现问题的情况下:
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_spring_02
此时我们对consumer的服务调用做降级处理
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_客户端_03

2.服务降级概述

整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。服务降级处理是在客户端实现完成的,与服务端没有关系。

Fallback相当于是降级操作。对于查询操作,我们可以实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回的值。 fallback方法的返回值一般是设置的默认值或者来自缓存。

2.2.引入依赖

首先在user-consumer中引入Hystix依赖:

<!--服务熔断组件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2.3.修改之前的Controller

在之前的Controller中添加熔断机制:

@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
// 一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public User get(@PathVariable("id") Long id) {
User u = this.userService.get(id);
if (null == u) {
throw new RuntimeException("该ID:" + id + "没有没有对应的信息");
}
return u;
}

public User processHystrix_Get(@PathVariable("id") Long id) {
User u=new User();
u.setId(110);
u.setUsername("该ID:" + id + "没有没有对应的信息,null--@HystrixCommand");
u.setNote("no this database in MySQL");
return u;
}

2.4.修改主启动类

修改consumer并添加新注解​​@EnableCircuitBreaker​

@SpringBootApplication
@EnableDiscoveryClient // 开启EurekaClient功能
@EnableFeignClients // 开启Feign功能
@EnableCircuitBreaker//对hystrixR熔断机制的支持
public class SpringcloudDemoConsumerApplication {

public static void main(String[] args) {
SpringApplication.run(SpringcloudDemoConsumerApplication.class, args);
}
}

2.5. 服务熔断测试

3个eureka先启动
主启动类SpringcloudDemoConsumerApplication

访问测试
​​​ http://127.0.0.1:88/consumer/get/2​玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_spring_04
如果对应的ID:3,数据库里面没有这个记录,我们报错后统一返回。
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_客户端_05

3. 服务降级优化-彻底解耦

修改microservicecloud-api工程,根据已经有的DeptClientService接口新建一个实现FallbackFactory接口的类DeptClientServiceFallbackFactory

/**
* @author bruceliu
* @create 2019-08-04 15:11
* @description
*/
@Component // 不要忘记添加
public class UserClientServiceFallbackFactory implements FallbackFactory<UserClientService> {


@Override
public UserClientService create(Throwable throwable) {
return new UserClientService() {
@Override
public List<User> queryUsers() {
return null;
}

@Override
public User get(Long id) {
User u=new User();
u.setId(110);
u.setUsername("该ID:\" + id + \"没有没有对应的信息,null--服务降级~~");
u.setNote("no this database in MySQL----服务降级!!!");
return u;
}
};
}
}
  • 修改consumer工程,UserClientService接口在注解@FeignClient中添加fallbackFactory属性值
/**
* @author bruceliu
* @create 2019-05-04 18:49
* @description Feign客户端
*/
@FeignClient(value = "SPRINGCLOUD-DEMO-SERVICE",fallbackFactory=UserClientServiceFallbackFactory.class)
public interface UserClientService {

@RequestMapping("/all")
public List<User> queryUsers();

@RequestMapping("/get/{id}")
public User get(@PathVariable("id") Long id);
}
  • 修改配置文件
# 开启服务熔断策略
feign.hystrix.enabled=true

3.1.测试

- 3个eureka先启动
- 微服务提供者启动
- 微服务消费者启动

正常访问测试:http://127.0.0.1:88/consumer/get/1
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_spring_06
故意关闭微服务提供者
玩转SpringCloud专题(十四)-SpringCloud之Hystrix服务降级_客户端_07
客户端自己调用提示
此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器。