本文我们来演示下Hystrix中解决雪崩效应的第一种方式降级的实现
先来看下正常服务调用的情况
当consumer调用provider服务出现问题的情况下:
此时我们对consumer的服务调用做降级处理
创建一个SpringCloud项目
添加Hystrix依赖,调用通过ribbon来负载均衡
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
修改application.properties文件,设置名称,端口和注册中心的信息
spring.application.name=eureka-ribbon-consumer-hystrix
server.port=9091
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://dpb:123456@eureka1:8761/eureka/,http://dpb:123456@eureka2:8761/eureka/
在启动类中添加注解开启熔断。@EnableCircuitBreaker
@EnableCircuitBreaker // 开启熔断 断路器
@EnableEurekaClient
@SpringBootApplication
public class SpringcloudEurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudEurekaConsumerApplication.class, args);
}
}
业务层代码中在getUsers方法中通过ribbon来获取负载均衡的地址,通过RestTemplate来调用服务,在方法头部添加@HystrixCommand注解,通过fallbackMethod 属性指定当调用的provider方法异常的时候的fallback方法为fallBack方法,然后在其方法中返回了托底数据。
@Service
public class UserService {
/**
* ribbon 负载均衡
* LoadBalancerClient 通过服务名称可以获取对应的服务的相关信息 ip port等
*/
@Autowired
private LoadBalancerClient loadBalancerClient;
@HystrixCommand(fallbackMethod = "fallBack")
public List<User> getUsers(){
// ServiceInstance 封装的有服务的基本信息 IP和端口等
ServiceInstance si = this.loadBalancerClient.choose("eureka-ribbon-provider");
StringBuilder sb = new StringBuilder();
sb.append("http://")
.append(si.getHost())
.append(":")
.append(si.getPort())
.append("/user");
System.out.println("服务地址:"+sb.toString());
// SpringMVC RestTemplate
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {};
// ResponseEntity:封装了返回值的信息
ResponseEntity<List<User>> response = rt.exchange(sb.toString(), HttpMethod.GET,null,type);
List<User> list = response.getBody();
return list;
}
/**
* 服务降级
* 返回托底数据的方法
* @return
*/
public List<User> fallBack(){
List<User> list = new ArrayList<>();
list.add(new User(3,"我是托底数据",22));
return list;
}
}
控制层代码仅仅是调用了业务层的方法
启动eureka注册中心,然后启动consumer服务,provider服务不用启动,这样我们访问consumer中的服务的时候就会出现异常,当我们浏览器看到托底数据的话,表示降级成功.
操作成功~ 案例代码:https://github.com/q279583842q/SpringCloud-dpb-Demo