Spring Cloud Hystrix 简单使用

770 阅读2分钟

1. 使用 Hystrix 的理由

微服务架构中,系统被拆分了很多模块对外提供服务,比如有 订单服务,库存服务,商品服务,支付服务,积分服务,发货服务。有这样的情况,比如支付成功了,需要减库存,通知发货,并给这次购买加上积分,但是积分服务全部挂了,订单调用积分的线程越积累越多,最后订单都不响应了,并且会影响到其他调用订单服务的线程,都卡住,最后弄得整个系统崩溃,不能对外服务了。在实际场景中,这是不允许的。因此呢,为了解决这个问题就出现了短路器机制了,这使得即使某些服务挂了,也会继续对外服务,至于有数据的不一致,可以通过其他的方法后续处理,比如积分挂了,那么调用积分服务时,在容错方法中将当前人,积分等信息保存到容错数据库中,以供后续恢复。

2. 准备

这里 在 上一篇 的 工程中直接使用

  1. 添加依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  1. 启动类添加 注解 @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调用时 处理

  1. 在 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注解 限流熔断。 结果提示信息: 获取订单列表失败";
    }
}
  1. 访问浏览器测试

这里就不用启动 order-service服务了

访问http://localhost:8080/ribbonCall/orderList

4. Feign调用时 处理

  1. 首先 开启 feign 对 hystrix的支持 在.yml配置文件中 写入
feign:
  hystrix:
    enabled: true
  1. 修改 @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();
}
  1. 熔断处理的类 FeignCallFailed
@Component
public class FeignCallFailed implements FeignCall {
    @Override
    public String orderList() {
        return "使用feign调用 获取订单列表 失败了";
    }
}
  1. 访问测试 同样不用启动 order-service 访问http://localhost:8080/feignCall/orderList