dubbo提供了服务降级的策略,我们首先看一下mock机制的降级原理,下面我们从源码的角度分析其调用过程。
如何使用mock服务降级
mock支持的配置大体分为2类,一类用于屏蔽,一类用于容错。可以通过dubbo-admin控制台下发配置。
这里我们只关注配置文件的使用。
屏蔽指的是消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。mock=
force:return+null ,这个不能在配置文件使用,通过控制台直接往注册中心写入该mock规则。
容错指的是消费方对该服务的方法调用在失败后,根据配置做不同的返回。
我这里就强调2种,一种是boolean值,默认的为false。如果配置为true,则缺省使用mock类名,即类名+Mock后缀,但该类要和暴露的服务路径相同,没有这个类,项目启动时会报Class Not Found 错误。
|
|
如上所示,我们配置了mock = true , 这时我们需要定义一个PushRpcServiceMock的类,它实现了PushRpcService接口,同时有一个默认的无参数构造函数(也可以不写,java会默认),注意这个类必须放在com.luckylau.api.service路径下,所以在本地代码要有这样的路径存在,专门为降级使用。
另外mock = “default”效果和mock=”true”一样。
这时候如果远程调用失败,就会访问PushRpcServiceMock类的返回。
另外一种是return null。
|
|
这时候如果远程调用失败,就会直接返回null,不抛出异常。
源码解析
首先是服务的引用过程,解决如何知道这个服务是mock的方式,ReferenceConfig的init()在执行ref = createProxy(map)之前有一步骤是checkStubAndMock,做了相关处理,包括如果配置mock = true但没有找到类名+Mock后缀,报Class Not Found 错误等。
然后是实际调用过程,我们跟踪一下源码(2.6版本),首先进入的是
|
|
当我们配置mock = “default” ,mock = “true” ,mock = “return null” 时
|
|
value的值为default, true, return+null。它们会进入fail-mock的逻辑,如果调用失败之后,首先判断异常的类型,包括业务错误类型:接口实现类中的方法抛出的错误 ,和非业务错误类型:网络错误、超时错误、禁止访问错误、序列化错误及其他未知的错误。业务错误类型直接抛出,非业务错误类型进入关键的处理:
|
|
|
|
|
|
我们单独分析配置mock = “true” 和 mock = “return null”的情况。此时用源码的demo。
首先看mock = “true” 的情况
|
|
|
|
在doMockInvoke中result = minvoker.invoke(invocation)非常重要,它的实现在com.alibaba.dubbo.rpc.support的MockInvoker类中,实现如下
|
|
回到mock = “true”配置时候,会走到这里,我们发现这里的invoker.invoke(invocation) ,调用的是AbstractProxyInvoker,最后会调用到我们定义的这个类DemoServiceMock。
|
|
|
|
然后mock = “return null” 的情况
在doMockInvoke中result = minvoker.invoke(invocation)非常重要,而mock = “return null” ,它执行到如下String mock = “return+null”
然后执行到下面,返回null