前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dubbo学习之本地存根实践

dubbo学习之本地存根实践

作者头像
沁溪源
发布2020-09-09 21:11:20
9280
发布2020-09-09 21:11:20
举报
文章被收录于专栏:沁溪源沁溪源

绪论

今天主要学习并实践dubbo的本地存根stub机制。首先了解一下官网文档对本地存根的介绍:

代码语言:javascript
复制
远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑。
比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等。
核心思想:API 中带上 Stub,客户端生成 Proxy 实例,**会把 Proxy 通过构造函数传给 Stub** ,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。

Stub会使用代理模式将原有的远程调用service进行包装,让使用者可以在远程服务调用前后做一些通用处理,非常适合做缓存容错,或者日志处理,异常包装等。故本地存根机制类似与AOP机制中的around advice(环绕增强); 则本地存根执行顺序: 1.服务消费者发起调用; 2.如果服务消费者端存在本地存根 Stub 的话,会先执行本地存根; 3.本地存根 Stub 持有远程服务的 Proxy 对象,Stub 在执行的时候,会先执行自己的逻辑(before),然后通过Proxy 发起远程调用,最后在返回过程之前也会执行自己的逻辑(after-returning) 4.如果远程服务的 Proxy 对象在执行过程中抛出了 exception,会执行服务消费端的本地伪装 Mock 的逻辑 (after-throwing)【后面再议】,返回容错数据,从而达到服务降级的目的。 如图:

在这里插入图片描述
在这里插入图片描述

实践

虽然dubbo官网简单给了本地存根的示例,但不是能够足以解决新手实战问题,其他博客千篇一律,没有几乎什么改进的地方,溪源学习的时候也是在花费了两个下班的时间搞定的实践,实属坎坷~ 写在前面

dubbo官网给出两种设置本地存根的示例

  • stub的属性值设置为实现类的全限定名;
  • stub的属性值,则默认设置为true
在这里插入图片描述
在这里插入图片描述

溪源主要给大家说下第二种方式:踩坑点如果默认将stub属性设置为true,则必须保证本地存根实现类以Stub命名结尾,例如UserServiceStub. 那为什么要这么设置呢????给大家贴一下源码ServiceConfig#checkAndUpdateSubConfigs()类中。 如果实现类不以Stub结束,那反射查找本地存根实现类便找不到,又谈何实现本地存根的逻辑呢~

在这里插入图片描述
在这里插入图片描述

踩坑点相信大家已经清楚,下面开始进入实战环节。

再看下dubbo官网本地存根,细品细品:

在这里插入图片描述
在这里插入图片描述

dubbo-demo-interface

  • 目录结构如下
在这里插入图片描述
在这里插入图片描述
  • UserService 简单定义一个方法
代码语言:javascript
复制
/**
 * @author wx
 * @date 2020/9/6 11:39 下午
 * 测试本地存根服务接口
 */
public interface UserService {
    /**
     * 根据用户名,返回用户名字
     * @param userId 用户ID
     * @return 用户名
     */
    String getUserName(String userId);
}
  • UserServiceStub
代码语言:javascript
复制
/**
 * @author wx
 * @date 2020/9/6 11:09 下午
 * 服务消费者实现接口,并实现本地存根逻辑
 */
public class UserServiceStub implements UserService {
    private static final String USER_ID  = "1503891";

    private final UserService userService;

    /**
     * 通过构造方法将服务接口代理对象(接口实现类对象)传入stub
     * @param userService
     */
    public UserServiceStub(UserService userService) {
        this.userService = userService;
    }

    @Override
    public String getUserName(String userId) {
        System.out.println("开始执行服务消费端本地存根逻辑");
        if (StringUtils.isBlank(userId)) {
            return "userId is null";
        }
        if (!USER_ID.equals(userId)) {
            return "user not exits";
        }
        String userName = userService.getUserName(userId);
        System.out.println("结束执行服务消费端本地存根逻辑");
        return userName;
    }
}

dubbo-demo-xml-provider

  • 目录结构
在这里插入图片描述
在这里插入图片描述
  • stub-provider.xml
在这里插入图片描述
在这里插入图片描述
  • UserProviderStubServiceImpl
代码语言:javascript
复制
/**
 * @author wx
 * @date 2020/9/6 11:09 下午
 * 服务消费者实现接口,并实现本地存根逻辑
 */
@Service
public class UserProviderStubServiceImpl implements UserService {
    private static final String USER_ID  = "1503891";

    @Override
    public String getUserName(String userId) {
        return USER_ID.equals(userId) ? "溪~源" : "";
    }
}
  • ProviderApplication
代码语言:javascript
复制
 /**
     * 服务端Stub测试
     * @throws IOException
     */
    private static void stubTest() throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/stub-provider.xml");
        context.start();
        System.in.read();
    }

dubbo-demo-xml-consumer

  • stub-consumer.xml 消费者端并没有新增实现类,但溪源为了代码的整洁与后期维护、梳理,选择了新建stub-consumer.xml配置文件和单元测试的模式实践.
在这里插入图片描述
在这里插入图片描述
  • ConsumerApplication
代码语言:javascript
复制
private static void stubTest() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/stub-consumer.xml");
        UserService stubService = context.getBean(UserService.class);
        String userName = stubService.getUserName("1503891");
        System.out.println(userName);

    }

启动

分别启动provider,consumer如图:

  • 测试1 将userId传为空
在这里插入图片描述
在这里插入图片描述
  • 测试2
在这里插入图片描述
在这里插入图片描述

到此为止,本地存根实践应用结束,大家对源码如何实现原理,可以借助此demo开始debug吧~

溪源初次接触dubbo本地存根机制,如文中存在错误之处,希望大家及时指正!

源码传送门:https://github.com/stream-source/dubbo/tree/master/dubbo-demo

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 绪论
  • 实践
    • dubbo-demo-interface
      • dubbo-demo-xml-provider
        • dubbo-demo-xml-consumer
          • 启动
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档