转载

使用NetflixHystrix的SpringCloud断路器

在微服务世界中,服务之间通讯时相当频繁,类似单体服务的方法调用,如果某个微服务中断或无法正常运行,则问题可能会级联到上游服务,造成连锁反应,故障爆炸。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专题

原文  https://www.jdon.com/springcloud/netflix-circuit-breaker.html
正文到此结束
Loading...