服务熔断机制是保护整个微服务出现雪崩,而服务降级是在熔断后的一个处理。
(ps:和 Ribbon、Feign 类似,Hystrix 已经凉凉了,在 SpringCloud 最新版本中,Hystrix 已经没有了,我们只能用它最后一个版本 2.2.9.RELEASE)
一、服务熔断的引入
这里我们是将服务熔断引入到商品模块,因为在我们项目中,订单模块是需要调用商品模块~~~
商品模块
pom
<!-- hystrix 断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
pom 中需要增加 Hystrix 的依赖
启动类
启动类中需要增加一个注解 @EnableHystrix,这样的话就可以开启 Hystrix 的组件了。
(ps:之前版本是通过 @EnableCircuitBreaker 进行开启,我已经尝试过了,2.2.9.RELEASE 这个版本已经不能通过这个方式进行开启了)
业务模块
业务模块中我们要将这个熔断加入进来
@GetMapping("/getCommodityPrice/{id}")
@HystrixCommand(fallbackMethod = "getCommodityPriceFallback")
public BigDecimal getCommodityPrice(@PathVariable(value = "id") String id) {
try {
// 线程睡眠 5 秒
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("这是 1000 端口的节点提供的服务");
return commodityService.getCommodityPrice(id);
}
/**
* 服务降级方法
* @return
*/
public BigDecimal getCommodityPriceFallback(String id) {
System.out.println("服务已经被熔断");
return BigDecimal.valueOf(-1L);
}
getCommodityPrice 就是我们要熔断的方法,我们在这个方法上增加一个注解:@HystrixCommand
@HystrixCommand 这个注解作用是,增加一个隔离线程,在我们方法正常的情况下,方法可以正常返回。当出现异常、超时(Hystrix 默认的超时时间是 1 秒钟)等情况,直接进行服务熔断,接着通过 fallbackMethod ,去指定降级后要走的一个方法。(注意!!!降级方法要和原方法返回值、参数相同,方法名称不同即可)
订单模块
订单模块我们主要简单修改一下业务代码
@PostMapping("/createOrder")
public Result createOrder(@RequestBody CreateOrderDTO createOrderDTO) throws Exception {
// ...
orderService.save(orders);
boolean nextStep = true;
List<OrderDetail> orderDetails = new ArrayList<OrderDetail>();
// ...
BigDecimal price = commodityOpenFeignService.getCommodityPrice(commodityId);
if(price.doubleValue() < 0) {
nextStep = false;
} else {
orderDetail.setCommodityPirce(price.multiply(BigDecimal.valueOf(dto.getCommodityCount())).setScale(2, BigDecimal.ROUND_FLOOR));
orderDetails.add(orderDetail);
}
}
if(nextStep) {
orderDetails.stream().forEach(detail -> {
orderDetailService.save(detail);
});
} else {
orderService.delete(orders.getId());
}
return Result.success();
}
我们增加一个 nextStep 是否还往下执行,还有一个 orderDetails 的集合。如果我们传递来的钱小于 0,那么我们就不要往下执行了,如果大于 0,就继续执行,将数据添加到 orderDetails 的集合中。
最后增加一个判断,如果 nextStep 是 true,也就是说所有订单中的商品都可以正确的拿到值,这样我们就一个一个的存起来。如果 nextStep 是 false,就直接将总的订单删除掉。
二、测试
将商品模块与订单模块修改好之后,我们启动 Erueka Server 集群,然后再将这两个模块也启动。
点击创建订单后,我们来看日志。
可以看到,服务已经被熔断了~~~
数据库也是空的。
三、商品模块代码修改
上面我们将这个服务已经熔断了,接下来,我们将这个线程休眠改成 500,也就是休眠 0.5 秒,再来看看结果。
重新启动商品模块的服务,再来点击创建订单。
首先是商品模块是正常提供服务,接着我们再来看数据库是否成功创建订单。
可以看到,是正常将订单添加进去了。
这一讲就讲到这里,有问题可以联系我:QQ 2100363119,欢迎大家访问我的个人网站:https://www.lemon1234.com
最近网站已经做好,并且已经上线,欢迎各位留言~~