1、参考
本地存根:http://dubbo.apache.org/en-us/docs/user/demos/events-notify.html
本地伪装:http://dubbo.apache.org/en-us/docs/user/demos/local-mock.html
2、本地存根
一般情况下,Consumer端只有接口,实现全部在Provider端。但有时候,Provider想让Consumer端执行部分逻辑,如ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等。
Provider端配置:
<dubbo:service interface="com.foo.BarService" stub="true" />
本来Stub的逻辑是由Provider提供的,但是上边的配置中,stub="true"但是却没有提供任务具体的代码。我想Provider应该会基于接口提供一个默认的Stub,不要这样用好了。
下边是另外一种配置方法:
<dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
这种配置的话,Provider端就提供了Stub的代码。
Provider提供的Stub的实现代码:
package com.foo;
public class BarServiceStub implements BarService {
private final BarService barService;
// The real remote proxy object is passed in through the constructor
public BarServiceStub(BarService barService){
this.barService = barService;
}
public String sayHello(String name) {
// The following code is executed on the client. You can do local ThreadLocal caching on the client side, or verify parameters, etc.
try {
return barService.sayHello(name);
} catch (Exception e) {
// You can return the mock data.
return "MockData";
}
}
}
注意它的构建方法,必需这样实现可以看到,实际上它就是普通的代理模式。
3、本地伪装
本地伪装的意思是当Provider端提供的服务不可用时,Consumer并不是直接抛出异常指出服务不可用,而是在本地伪造数据,不抛出异常,通常用于服务降级。
配置:
<dubbo:reference interface="com.foo.BarService" mock="true" />
上边的话,本地会生成一个默认的Mock。
或者:
<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
Consumer端Mock代码的实现:
package com.foo;
public class BarServiceMock implements BarService {
public String sayHello(String name) {
// You can return mock data, this method is only executed when an RpcException is thrown.
return "mock data";
}
}
当实现并设置好mock后,Consumer端在调用Provider时,如果抛出Rpc异常,那么异常会被捕获,并且会触发mock代码的执行,很显然的,Consumer端将不需要再捕获Rpc异常了。
后边还有一堆没什么用的特性,不写了。
Stub与Mock很像,比较一下不同点:
配置不同:
Stub的配置发生在Provider端:
<dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
Mock的配置发生在Consumer端:
<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
提供代码的角色不同:
Stub中的代码由Provider提供,Mock中的代码由Consumer端实现。
触发条件不同:
Stub总是会执行,实现上Consumer端对这个东西无感。
Mock是在Consumer调用服务出现异常时触发。
我觉得上边这两个东西没有太大的用处,开发者很容易自行实现。就实现一个代理类,代理的就是Provider端实现的那个接口。然后里边的逻辑由Consumer开发者自行实现,这样也很方便。