使用Netflix Hystrix的Spring Cloud断路器

  在微服务世界中,服务之间通讯时相当频繁,类似单体服务的方法调用,如果某个微服务中断或无法正常运行,则问题可能会级联到上游服务,造成连锁反应,故障爆炸。Netflix创建了Hystrix库,实现了Circuit Breaker断路器模式以解决这些问题。我们可以使用Spring Cloud Netflix Hystrix断路器来保护微服务免受级联故障的影响。

 HYSTRIX断路器能够增强系统的弹性,在微服务无法访问时重试,重试几次后就放弃,也能进行快速失效,不把时间耗费在无谓的等待上,防止故障爆炸。它可提供仪表板dashboard监控实时情况。

 首先,将Hystrix启动程序添加到目录服务:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

要启用Circuit Breaker,在入口点类上添加@EnableCircuitBreaker注释:


@SpringBootApplication
@EnableCircuitBreaker
public class CircuitbreakerApplication {

在我们自己的方法上使用@HystrixCommand注释,可以控制超时或回退。

我们准备结合前面Feign客户端案例,验证一下断路器如何在重要数据的获取上起到关键作用,为此,需要在pom.xml中还要引入feign、eureka和ribbon依赖包,具体可见前面Feign项目的pom.xml。同时,也将以Ariticile领域模型为案例,假设在获取远程所有Article时出错,我们如何继续业务逻辑?

在实际中涉及到金钱方面的编程都需要额外小心,如果没有底层事务支持,那么我们业务上要进行失败回退处理,为了模拟这一实际场景,首先给Article增加一个price字段,表示每篇文章的价格,我们在消费者这里获取远程生产者所有文章的价格,计算总价,如果获取远程出错,我们就给一个默认价格99.99元,这个数值数值是最大化保证系统自身利益,如同自动柜员机取款时,如果碰到网络问题,最大只能取100元,对于银行损失100元也不是什么大问题,而且这种情况极少发生,同时保证ATM机用户能够正常操作,这样做的好处是,控制了网络故障时发生时最大损失。

下面是我们的消费服务代码:


@Service
public class OurConsumerService {
@Autowired
ConsumerService consumerService;

@HystrixCommand(fallbackMethod = "countArticleDefault")
public Float countArticle(){
List<Article> articles = consumerService.getAllArticles();
float fee = 0.0f;
for (Article article : articles) {
fee = fee + article.getPrice();
}
return fee;
}

public Float countArticleDefault(){
return 99.99f;
}
}

 

上面代码获取远程ConsumerService,遍历Articles集合,计算总价,如果在获取时出错,则执行下面一个默认方法,直接返回总价为99.99元。ConsumerService代码没有变动,是个Feign客户端:


@FeignClient(name="PengProducerService")
public interface ConsumerService {

@GetMapping("/articles")
List<Article> getAllArticles();
}

 

现在可以启动注册服务器,启动生产者服务,先为生产者服务准备几条Article数据:

[
{
"id": 1,
"title": "my 第1个 post",
"body": "this is 1body",
"startDate": null,
"price": 1111.11
},
{
"id": 2,
"title": "my 第1个 post",
"body": "this is 1body",
"startDate": null,
"price": 1111.11
},
{
"id": 3,
"title": "my 第2个 post",
"body": "this is 2body",
"startDate": "2018-01-01T00:00:00.000+0000",
"price": 143.45
}
]

然后运行消费者服务,获得结果如下:

##############fee is 2365.67

如果我们将生产者服务关闭,再运行消费者服务,应该是获得默认值:

##############fee is 99.99

总结,使用断路器能够提高我们系统的数据可靠性,依据CAP定理,在存在网络分区P情况下,也就是发生通讯断路了,通讯的两边的数据肯定不一致了,虽然各自都可以使用,那么断路器为我们手工处理这种不一致提供了方便。

本章下载源码:百度网盘

Spring Cloud专题

 

猜你喜欢