1. 使用 Hystrix 的理由
微服务架构中,系统被拆分了很多模块对外提供服务,比如有 订单服务,库存服务,商品服务,支付服务,积分服务,发货服务。有这样的情况,比如支付成功了,需要减库存,通知发货,并给这次购买加上积分,但是积分服务全部挂了,订单调用积分的线程越积累越多,最后订单都不响应了,并且会影响到其他调用订单服务的线程,都卡住,最后弄得整个系统崩溃,不能对外服务了。在实际场景中,这是不允许的。因此呢,为了解决这个问题就出现了短路器机制了,这使得即使某些服务挂了,也会继续对外服务,至于有数据的不一致,可以通过其他的方法后续处理,比如积分挂了,那么调用积分服务时,在容错方法中将当前人,积分等信息保存到容错数据库中,以供后续恢复。
2. 准备
这里 在 上一篇 的 工程中直接使用
- 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 启动类添加 注解 @EnableCircuitBreaker
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class LinnWebApplication {
public static void main(String[] args) {
SpringApplication.run(LinnWebApplication.class, args);
}
/**
* @LoadBalanced 必须添加 否则会报 java.net.UnknownHostException 找不到服务名称
* @return
*/
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
3. Ribbon调用时 处理
- 在 ribbon 包下的 RibbonCall 改为如下
@Component
public class RibbonCall {
/**
* 注入 restTemplate
*/
@Autowired
private RestTemplate restTemplate;
/**
* 调用 订单服务 获取订单列表
* 直接在URL中写明 使用ORDER-SERVICE 表示订单服务,后接地址
*
* @HystrixCommand 熔断处理 其中 fallbackMethod 指定 处理的方法
* @return
*/
@HystrixCommand(fallbackMethod = "orderListFailed")
public String orderList(){
return restTemplate.getForObject("http://ORDER-SERVICE/order/list",String.class);
}
/**
* 容错处理
* @return
*/
public String orderListFailed() {
return "ribbon 使用Hystrix @HystrixCommand注解 限流熔断。 结果提示信息: 获取订单列表失败";
}
}
- 访问浏览器测试
这里就不用启动 order-service服务了
访问http://localhost:8080/ribbonCall/orderList
4. Feign调用时 处理
- 首先 开启 feign 对 hystrix的支持 在.yml配置文件中 写入
feign:
hystrix:
enabled: true
- 修改 @FeignClient 添加fallback支持 fallback 指定的类即为 熔断处理的 类
/**
* @FeignClient 的value 值为 注册的服务的名字 即:${spring.application.name}的值
*/
@FeignClient(value = "ORDER-SERVICE",fallback = FeignCallFailed.class)
@Component
public interface FeignCall {
/**
* 获取订单列表
* 注意这里 要和 order-service中的那个方法一致 ,并注意 访问路径
* @return
*/
@GetMapping("order/list")
String orderList();
}
- 熔断处理的类 FeignCallFailed
@Component
public class FeignCallFailed implements FeignCall {
@Override
public String orderList() {
return "使用feign调用 获取订单列表 失败了";
}
}
- 访问测试 同样不用启动 order-service 访问http://localhost:8080/feignCall/orderList