服务降级
对应的@FeignClient中的fallback属性则是服务容错中很关键的服务降级的具体实现,来看看OrderServiceFallBack类:
public class OrderServiceFallBack implements OrderServiceClient { @Override public BaseResponse<OrderNoResVO> getOrderNo(@RequestBody OrderNoReqVO orderNoReq) { BaseResponse<OrderNoResVO> baseResponse = new BaseResponse<>() ; OrderNoResVO vo = new OrderNoResVO() ; vo.setOrderId(123456L); baseResponse.setDataBody(vo); baseResponse.setMessage(StatusEnum.FALLBACK.getMessage()); baseResponse.setCode(StatusEnum.FALLBACK.getCode()); return baseResponse; } }
该类实现了OrderServiceClient接口,可以很明显的看出其中的getOrderNo()方法就是服务降级时所触发的逻辑。
光有实现还不够,我们需要将改类加入到Spring中管理起来。这样上文中@FeignClient的configuration属性就起到作用了,来看看对应的OrderConfig的代码:
@Configuration public class OrderConfig { @Bean public OrderServiceFallBack fallBack(){ return new OrderServiceFallBack(); } @Bean public OrderServiceFallbackFactory factory(){ return new OrderServiceFallbackFactory(); } }
其中new OrderServiceFallBack()并用了@Bean注解,等同于:
<bean id="orderServiceFallBack" class="com.crossoverJie.order.feign.config.OrderServiceFallBack"> </bean>
这样每当请求失败就会执行回退逻辑,如下图:
值得注意的是即便是执行了回退逻辑断路器也不一定打开了,我们可以通过应用的health端点来查看Hystrix的状态。
ps:想要查看该端点需要加入以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
就拿刚才的例子来说,先关闭Order应用,在Swagger访问下面这个接口,肯定是会进入回退逻辑:
@RestController @Api("用户服务API") @RequestMapping(value = "/userService") @Validated public interface UserService { @ApiOperation("hystrix容错调用") @RequestMapping(value = "/getUserByHystrix", method = RequestMethod.POST) BaseResponse<OrderNoResVO> getUserByHystrix(@RequestBody UserReqVO userReqVO) ; }
查看health端点:
发现Hystrix的状态依然是UP状态,表明当前断路器并没有打开。
反复调用多次接口之后再次查看health端点:
发现这个时候断路器已经打开了。
这是因为断路器只有在达到了一定的失败阈值之后才会打开。
输出异常
进入回退逻辑之后还不算完,大部分场景我们都需要记录为什么回退,也就是具体的异常。这些信息对我们后续的系统监控,应用调优也有很大帮助。
实现起来也很简单:
上文中在@FeignClient注解中加入的fallbackFactory = OrderServiceFallbackFactory.class属性则是用于处理回退逻辑以及包含异常信息:
/** * Function:查看fallback原因 * * @author crossoverJie * Date: 2017/9/4 00:45 * @since JDK 1.8 */ public class OrderServiceFallbackFactory implements FallbackFactory<OrderServiceClient>{ private final static Logger LOGGER = LoggerFactory.getLogger(OrderServiceFallbackFactory.class); @Override public OrderServiceClient create(Throwable throwable) { return new OrderServiceClient() { @Override public BaseResponse<OrderNoResVO> getOrderNo(@RequestBody OrderNoReqVO orderNoReq) { LOGGER.error("fallback:" + throwable); BaseResponse<OrderNoResVO> baseResponse = new BaseResponse<>() ; OrderNoResVO vo = new OrderNoResVO() ; vo.setOrderId(123456L); baseResponse.setDataBody(vo); baseResponse.setMessage(StatusEnum.FALLBACK.getMessage()); baseResponse.setCode(StatusEnum.FALLBACK.getCode()); return baseResponse; } }; } }
代码很简单,实现了FallbackFactory接口中的create()方法,该方法的入参就是异常信息,可以按照我们的需要自行处理,后面则是和之前一样的回退处理。
2017-09-21 13:22:30.307 ERROR 27838 --- [rix-sbc-order-1] c.c.o.f.f.OrderServiceFallbackFactory : fallback:java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: sbc-order。
Note:
fallbackFactory和fallback属性不可共用。


