dubbo的本地存根(Stub)与本地Mock

stub

远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,那么就在服务消费者这一端提供了一个Stub类,然后当消费者调用provider方提供的dubbo服务时,客户端生成 Proxy 实例,这个Proxy实例就是我们正常调用dubbo远程服务要生成的代理实例,然后消费者这方会把 Proxy 通过构造函数传给 消费者方的Stub ,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。会通过代理类去完成这个调用,这样在Stub类中,就可以做一些额外的事,来对服务的调用过程进行优化或者容错的处理。附图:

mock:

RPC在服务异常时,请求返回mock的(假)数据,而不是简单的抛出异常,达到服务降级和本地mock的效果.只有在服务抛出异常时才会调用。

stub会做一些日志或者其他校验判断是否进行服务的调用而mock主要用于服务降级的作用

服务接口:

public interface DemoService {

    String sayHello(String name);

}

服务端实现

public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {

        System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
    }

}

服务端配置:

  <!-- provider's application name, used for tracing dependency relationship -->
    <dubbo:application name="demo-provider"/>

    <!-- use multicast registry center to export service -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"/>

    <!-- use dubbo protocol to export service on port 20880 -->
    <dubbo:protocol name="dubbo" port="20881"/>

    <!-- service implementation, as same as regular local bean -->
    <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>

    <!-- declare the service interface to be exported -->
    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>

consumer的实现

public class Consumer {

    public static void main(String[] args) {
        //Prevent to get IPV6 address,this way only work in debug mode
        //But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or not
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
        context.start();
        DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
        int count  = 0;
        while (true) {
            try {
                Thread.sleep(1000);
                String hello = demoService.sayHello("world"+ count++); // call remote method
                System.out.println(hello); // get result

            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }

    }
}

stub的实现:


public class DemoServiceStub implements DemoService {
    private final DemoService demoService;

    public DemoServiceStub(DemoService demoService) { // #2
        this.demoService = demoService;
    }
    @Override
    public String sayHello(String name) {
        if(name.contains("2")){
            return "异常信息";
        }else{
            return demoService.sayHello(name);
        }
    }

}

mock的实现:

public class DemoServiceMock implements DemoService {

    @Override
    public String sayHello(String name) {
        return "server fail mock " + name;
    }

}

配置信息:

 <dubbo:application name="demo-consumer"/>

    <!-- use multicast registry center to discover service -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"/>

    <!-- generate proxy for the remote service, then demoService can be used in the same way as the
    local regular interface -->
    <dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService" mock="com.alibaba.dubbo.demo.consumer.DemoServiceMock" stub="com.alibaba.dubbo.demo.consumer.DemoServiceStub"/>

服务调用的整体结果:

当我们停止provider会触发mock

 

手贱的我,把mock去掉,发现stub功能上完全和mock差不多,what。。。。。这是什么个情况。。

探寻真理的路上,我果断的选择了debug,发现这个demoservice是DemoServiceStub,这样我们就可以猜测出这很明显是proxy的老套路了,那proxy又是在那实现的呢?????

通过代理工厂创建了代理对象stub,所以消费者中的注入的demoservice本身就是stub实体

我们继续看一下mock的实现,调用服务失败之后的逻辑

所以本质上本地存根和mock的实现方法是不一样的,虽然能达到相同的结果

 

回复  8888可以领取面试资料

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术王老五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值