前言
看过 应用限流的朋友应该知道,限流的根本目的就是为了保障服务的高可用。
本次再借助SpringCloud
中的集成的Hystrix
组件来谈谈服务容错。
其实产生某项需求的原因都是为了解决某个需求。当我们将应用进行分布式模块部署之后,各个模块之间通过远程调用的方式进行交互(RPC
)。拿我们平时最常见的下单买商品来说,点击下单按钮的一瞬间可能会向发送的请求包含:
- 请求订单系统创建订单。
- 请求库存系统扣除库存。
- 请求用户系统更新用户交易记录。
这其中的每一步都有可能因为网络、资源、服务器等原因造成延迟响应甚至是调用失败。当后面的请求源源不断的过来时延迟的资源也没有的到释放,这样的堆积很有可能把其中一个模块拖垮,其中的依赖关系又有可能把整个调用链中的应用Over最后导致整个系统不可能。这样就会产生一种现象:雪崩效应
。
之前讲到的限流也能起到一定的保护作用,但还远远不够。我们需要从各个方面来保障服务的高可用。
比如:
- 超时重试。
- 断路器模式。
- 服务降级。
等各个方面来保障。
使用Hystrix
SpringCloud
中已经为我们集成了Netflix
开源的Hystrix
框架,使用该框架可以很好的帮我们做到服务容错。
Hystrix简介
下面是一张官方的流程图:
简单介绍下:
在远程调用时,将请求封装到HystrixCommand进行同步或是异步调用,在调用过程中判断熔断器是否打开、线程池或是信号量是否饱和、执行过程中是否抛出异常,如果是的话就会进入回退逻辑。并且整个过程中都会收集运行状态来控制断路器的状态。
不但如此该框架还拥有自我恢复功能,当断路器打开后,每次请求都会进入回退逻辑。当我们的应用恢复正常后也不能再进入回退逻辑吧。
所以hystrix
会在断路器打开后的一定时间将请求发送到服务提供者,如果正常响应就关闭断路器,反之则继续打开,这样就能很灵活的自我修复了。
Feign整合Hystrix
在之前的章节中已经使用Feign
来进行声明式调用了,并且在实际开发中也是如此,所以这次我们就直接用Feign来整合Hystrix。
使用了项目原有的sbc-user,sbc-order
来进行演示,调用关系如下图:
User应用
通过Order
提供出来的order-client
依赖调用了Order
中的创建订单服务。
其中主要修改的就是order-client
,在之前的OrderServiceClient
接口中增加了以下注解:
@RequestMapping(value="/orderService") @FeignClient(name="sbc-order", // fallbackFactory = OrderServiceFallbackFactory.class, // FIXME: 2017/9/4 如果配置了fallback 那么fallbackFactory将会无效 fallback = OrderServiceFallBack.class, configuration = OrderConfig.class) @RibbonClient public interface OrderServiceClient extends OrderService{ @ApiOperation("获取订单号") @RequestMapping(value = "/getOrderNo", method = RequestMethod.POST) BaseResponse<OrderNoResVO> getOrderNo(@RequestBody OrderNoReqVO orderNoReq) ; }
由于Feign已经默认整合了Hystrix
所以不需要再额外加入依赖。