前面的小节里我们学习了Hystrix的核心功能,今天我们拿一个最常用的功能来展开,那就是“服务降级”。
作为SpringCloud中的执法部门-六扇门,Hystrix监管着服务的一举一动,不管是超时还是异常抛出,但凡有违法乱纪的现象发生,就会被强制放到fallback里进行改造。可是,每个应用都有一长串的服务,那全部都交给Hystrix这能管得过来吗?
服务降级原理解析 - 图1
Hystrix可不是所有服务都监督,毕竟六扇门人力有限,他们只盯梢一些关键人物,给每个关键人物指派一个锦衣卫,但凡有异常发生,立即动手。接下来,我们就来看看六扇门的锦衣卫是如何秉公执法的。

盯梢名单 - @HystrixCommand

现在流行苍蝇老虎一起打,可我们六扇门不在乎小苍蝇,只盯大老虎。对那些一旦发生异常,影响特别恶劣,但是还有补救措施的,我们就安排一个锦衣卫贴身监视。

  1. @HystrixCommand(fallbackMethod = "putInPrison")
  2. public String bigTiger() {
  3. throw RuntimeException("Eat People");
  4. }

上面就是我们的贴身锦衣卫@HystrixCommand注解,直接管在大老虎(具体Method方法)的头上,没有指派锦衣卫的方法就可以放飞自我了,Hystrix不会管你的。
@HystrixCommand注解中指定了一个fallbackMethod,这里就是大老虎进行改造的地方,也就是降级逻辑所在的方法名。注意,降级方法的方法签名(参数列表)要和原方法保持一致,也就是说,如果原方法声明了一个参数String,那么降级方法也要声明同样的参数,Hystrix会原封不动的把当前参数传递给降级方法。
当Hystrix和Feign共同使用的时候,还有一种配置方式,那就是在FeignClient注解中指定一个class,在这个class里可以处理Feign接口中声明的所有方法的降级需求。

  1. @FeignClient(name = "feign-service-provider", fallback = Fallback.class)
  2. public interface MyHelloService extends HelloService {
  3. }

在稍后稍后小节中,我们将把上述两个方案同时应用到demo中。

锦衣卫工作流程 - 异常捕捉

如果同学直接去阅读Hystrix服务降级的源码,相信有很有效的直接劝退的作用。Hystrix的源码大量基于RxJava,在实现上比较接近函数式语言的风格,运用了大量的异步回调函数和事件驱动,层层嵌套十分崩溃,这对有JavaScript或其他函数语言经验的同学会容易理解一些(我估计Hystrix研发团队一定有资深JavaScript背景的研发人员)。
如果大家平时阅读源码的经验不多,想弄明白这里面的道道可以说非常的难。老师2年前完整阅读过Hystrix代码,今天回过头再看的时候,也仔细debug了好一会儿才把异常捕捉的底层实现摸清。老师在源码阅读环节也会带大家从头到尾debug一把,跳过繁文缛节,只看最核心的部分。尽管Hystrix是一个久经考验的开源项目,但坦白的说,我对Hystrix的代码结构和可维护性保持谨慎悲观的态度。
为了避免直接劝退,这里的流程图以业务流为主,不涉及具体类名和方法名。不过我鼓励同学们自己去研究一下代码,这样有不懂的地方,就可以带着问题去看代码讲解视频:
服务降级原理解析 - 图2

  1. @HystrixCommand: 安插在方法上的锦衣卫,标识此方法由Hystrix监管
  2. AspectJ:运用Spring的切面能力,给带有@HystrixCommand注解的方法配置了切面点,在方法调用的时候,将首先执行切面逻辑。大家可以借这个机会,顺带复习一下Spring的AOP切面编程(最好能够通过一个简单的小任务加深理解,比如自己定义一个注解,并且给这个注解配置切面完成一个简单逻辑,比如:将带有自定义注解的方法的执行时间打印到log中)
  3. Request Cache:(下一节会讲到RequestCache策略)
    • 如果处于开启状态,则尝试用CacheKey从本地缓存中获取数据,也就不用发起方法调用了
    • 如果处于关闭状态,就继续往下走到最烧脑的部分,Observer
  4. 注册Observer:Observer是观察者模式(在RxJava中又叫Observable),但这里只是一个幌子,这个Observer背后运用RxJava注册了一堆异步回调函数,当方法正常执行、异常抛出、结束或其他状态的时候,将会触发对应的回调函数进行处理,而且回调函数里面还会嵌套回调函数。(Hystrix开发团队是不是有个很怕失业的程序员?写这么复杂是要别人没法接手吗?)
  5. 发起调用:在发起调用之前,将会检查熔断状态,如果断路器当前处于开启的状态,那么将直接走向fallback流程。如果断路器处于关闭,则发起真正的调用
  6. 异常,又见异常:前面你来我往这么久,就是等方法调用抛异常。异常触发了步骤4中注册的回调函数,然后直接转给了降级方法

    小结

    这一节带大家了解了Hystrix的降级业务流程,下一节我们就来点轻松的话题,看看这帮六扇门的锦衣卫们,对这些进了fallback的家伙都有什么严刑逼供(降级)手段。
    学习Tips:我鼓励同学们自己深入研究Hystrix代码,相比前面几个组件来说Hystrix的代码阅读难度有大幅提升。有人说学习应该先易后难,老师自己比较喜欢先难后易,这个感觉就像学钢琴,如果直接从10级谱子开始弹,虽然初期非常艰难,但一旦学会之后,前面9级8级这些谱子就不在话下了。当然了,好的学习方法首先得要适合自己,不管从难到易还是从易到难,适合自己就是最好的。在学习过程中,解决越困难的问题,你就会积累越多的自信心,不畏难且迎难而上,也是我们技术人员的工作态度。