`

dubbo优化之本地存根缓存前置

 
阅读更多

 

    今年做了一个dubbo的本地存根优化,觉得卓有成效所以在这记录分享下。

 

    问题:

      1. Account服务如何将日均调用从千万优化到百万?看到这个问题,你是否也在纳闷,如果业务量没有下来,调用量怎么会下来呢?

 

      答:其实真可以有,Account的getAccount之前dubbo调用量在1000w+,优化到现在基本在100w+左右。如果Account服务的业务方可以充分使用Account的公共资源如缓存等,那么就可以减少dubbo的RPC调用,但是又有个问题,如何做到让业务方不care缓存调用的相关逻辑呢?这个我们用了一个小小的技巧,dubbo的stub。

 

      2. dubbo的stub是啥?

      答:请参照dubbo官网链接

 

    技术实现:

      1. 流程图如下

       
      

   

      2.系统架构图如下:

      
      

 

    3. 缺点

      a) 缓存地址变化,所以使用本地存根的消费者都需要修改配置

      b) 如果缓存从nkv切换到ncr则需要升级jar包中的缓存,影响所有的使用本地存根的消费者。

      c) 无法监控哪些消费者使用者本地存根。

 

    核心代码:

    

// 核心配置支持配置文件和zk的配置方式
public class AccountConfig {
    /** NKV 配置 */
    public String accountNkvConfig;
    public String masterUrl;
    public String slaveUrl;
    public Short namespace;
    public Long timeOut;

    /** 开关控制是否走缓存优化 */
    public boolean useCacheOptimize = true;

    /** Disconf配置 */
    private ConfigService configService;

    /** 0 未初始化, 1 disconf  2 properties */
    private int initType = 0;

    public void init() {
        if(null != configService) {
            accountNkvConfig = configService.getString("account_nkv_config");
            initConfig();
            if(checkConfig()) {
                initType = 1;
            }
        } else {
            if(checkConfig()) {
                initType = 2;
            }
        }
    }

    /** 初始化配置 */
    public void initConfig() {
        try {
            if(StringUtils.isNotBlank(accountNkvConfig)) {
                JSONObject nkvConfigJSON = JSONObject.parseObject(accountNkvConfig);
                masterUrl = nkvConfigJSON.getString("master");
                slaveUrl = nkvConfigJSON.getString("slave");
                namespace = nkvConfigJSON.getShort("namespace");
                timeOut = nkvConfigJSON.getLong("timeout");
            }
        } catch (Exception e) {

        }
    }

    public boolean checkConfig() {
        if( StringUtils.isBlank(masterUrl) || StringUtils.isBlank(slaveUrl) || null == namespace || null == timeOut ) {
            return false;
        }
        return true;
    }


    public boolean getUseCacheOptimize() {
        if(null != configService) {
            return configService.getBoolean("use_cache_optimize", true);
        }
        return useCacheOptimize;
    }
}

  

 

    

// 初始化cache
public class CacheClient extends MemcacheManagerImpl{

    @Autowired
    public AccountConfig accountConfig;

    public void init() {
        try {
            MemcacheTransactionManagerImpl spaceMemcacheTransactionManager = new MemcacheTransactionManagerImpl();
            DefaultNkvClient nkvClient = new DefaultNkvClient();
            nkvClient.setMaster(accountConfig.masterUrl);
            nkvClient.setSlave(accountConfig.slaveUrl);
            nkvClient.setGroup("group_1");
            nkvClient.setCompressEnabled(true);
            nkvClient.init();

            setMemcacheTransactionManager(spaceMemcacheTransactionManager);
            setClient(nkvClient);
            setNamespace(accountConfig.namespace);
            setTimeoutMilliseconds(accountConfig.timeOut);
        } catch (Exception e) {
            LogUtil.accountOpt.info("Account init Cache Exception ", e);
        }
    }
}

 

 

 

    

// 判断cache是否初始化成功
@Component
public class ApplicationContextHolder implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    /** 是否初始化成功 */
    public static boolean isInitSuccess = false;

    public static AccountConfig accountConfig = null;

    public static  Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHolder.applicationContext = applicationContext;
        try {
            Object accountConfigObj =  applicationContext.getBean("accountConfig");
            LogUtil.accountOpt.info("Account Cache Config : " + (null == accountConfigObj ? null : accountConfigObj.toString()));
            if(null != accountConfigObj) {
                accountConfig = (AccountConfig) accountConfigObj;
                if(accountConfig.getInitType() > 0) {
                    Object memcacheManagerObj = applicationContext.getBean("cacheClient");
                    if(null != memcacheManagerObj) {
                        isInitSuccess = true;
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.accountOpt.error("Account Cache Init exception " , e);
        }
        LogUtil.accountOpt.info("Account Cache Init Result : "  + isInitSuccess);
    }
}

 

 

   

   

// 使用本地存根
public class AccountServiceStub extends CacheManager<Account> implements AccountService {
    // dubbo会自动注入该对象,使用注解无效
    private AccountService accountService;

    public AccountServiceStub(AccountService accountService) {
        this.accountService = accountService;
    }

    @Override
    public Account queryByUserId(Long userId) {
        return accountService.queryByUserId(userId);
    }
}

 

 

   

<!-- dubbo消费方配置 -->
<dubbo:reference  id="accountService"  
  interface="com.xxx.account.service.AccountService"              
  stub="com.xxx.account.service.AccountServiceStub" />

 

 


 

 

 

 

  • 大小: 73.5 KB
  • 大小: 94.8 KB
分享到:
评论

相关推荐

    dubbo+zookeeper缓存方案

    Dubbo 和 Zookeeper 结合使用的缓存方案是分布式系统中常见的设计,主要目的是解决多节点环境下数据一致性的问题,确保在各个节点之间的缓存能够实时同步更新。以下将详细阐述这个方案的具体实现、工作原理以及其...

    Dubbo本地存根是什么,Dubbo本地伪装又是什么?.doc

    Dubbo 本地存根和本地伪装详解 在 Dubbo 框架中,本地存根和本地伪装是两个重要的概念,它们都是 Dubbo 框架提供的一些机制,以便于我们在分布式系统中更好地控制服务调用过程。本文将详细介绍 Dubbo 本地存根和...

    dubbo-cache:@DubboCache提供dubbo消费者直接使用缓存的能力,当缓存不存在时,再访问远程dubbo服务

    提供dubbo消费者直接使用缓存的能力,当缓存不存在时,再访问远程dubbo服务。 相对于dubbo默认的缓存机制,此项目具有如下优点: 原生dubbo cache机制只能缓存结果到消费者jvm中,并且cache key不能选择。 缓存key...

    zk+dubbo+spring本地工程

    【标题】"zk+dubbo+spring本地工程"指的是一个整合了Zookeeper、Dubbo和Spring框架的本地开发环境。这个项目可能是一个分布式服务治理的示例或者开发模板,旨在帮助开发者快速搭建具备服务注册与发现、远程调用等...

    dubbo本地测试服务

    本主题聚焦于“dubbo本地测试服务”,旨在帮助开发者在本地环境中进行服务提供者连接、数据发送测试以及接口调试,从而确保服务的正确性和稳定性。 一、Dubbo简介 Dubbo由阿里巴巴开源,其核心功能包括服务注册与...

    本地搭建一套dubbo架构demo

    本地搭建一套dubbo架构demo,包括zookeeper及后台DubboKeeper dubbo-admin后台管理 dubbo-monitor简易监控中心

    dubbo-demo 本地调通直接能运行起来

    【标题】"dubbo-demo 本地调通直接能运行起来" 涉及到的核心知识点主要是Dubbo框架的使用和本地环境配置。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了丰富的服务治理功能,是阿里巴巴集团贡献给社区的...

    SpringBoot整合Dubbo增强版

    总之,SpringBoot整合Dubbo增强版是一个优化过的解决方案,它解决了在SpringBoot中使用Dubbo时可能出现的问题,使得开发过程更加顺畅,同时也保留了Dubbo的强大服务治理功能,为微服务架构提供了坚实的基础。

    Dubbo(七)------服务运行的三种方式

    在Dubbo这个高性能、轻量级的开源Java RPC框架中,服务运行的三种方式是其核心功能之一,它们分别是:本地存根(Local Stub)、远程代理(Remote Proxy)以及缓存代理(Cache Proxy)。理解这三种方式对于优化服务...

    dubbo 2.8.4.jar 和安装本地库命令

    dubbo 2.8.4 jar dubbox 安装本地库教程支持rest 1,在jar包所在文件夹,点击鼠标右键-在此处打开命令窗口 2,输入命令 3. mvn install:install-file -Dfile=E:/dubbo-2.8.4.jar -DgroupId=...

    本地dubbo安装教程.zip

    首先,我们从"本地dubbo安装教程.zip"这个压缩包开始。这个压缩包包含了安装所需的所有文件和教程,确保你能够顺利地在本地环境中设置好这两个组件。 1. **解压压缩包**: 在开始安装之前,你需要先将下载的压缩包...

    DUBBO本地搭建及小案例

    ### DUBBO本地搭建及小案例 #### 一、DUBBO概述 DUBBO是一款高性能、轻量级的开源微服务框架,它提供了一整套的方法论来帮助开发者更好地构建分布式系统和服务化应用。DUBBO的核心功能包括服务治理、服务调用与...

    关于Dubbo异步调用的优化

    对原有的dubbo远程调用的异步的缺陷性进行了优化方案

    Dubbo配置文件依赖的本地DTD

    总的来说,理解并掌握Dubbo配置文件中的DTD使用对于优化服务的部署和维护至关重要。合理利用本地DTD可以提高系统性能,增强服务的可靠性,是每个Dubbo开发者应该掌握的一项技能。在实际操作中,结合XML的DTD和XSD...

    zookeeper+dubbo本地工程demo

    快速搭建的一个本地Dubbo demo,方便学习Dubbo。 注:该资源的使用可以参考文章:http://blog.csdn.net/accp_fangjian/article/details/51658292

    Dubbo入门之HelloWorld

    在IT行业中,分布式服务框架是构建大型互联网应用的关键技术之一,Dubbo作为阿里巴巴开源的一款高性能、轻量级的Java RPC框架,受到了广泛的关注和使用。本文将基于"Dubbo入门之HelloWorld"的主题,深入探讨如何从零...

    本地搭建Dubbo-服务的示例Demo

    ### 本地搭建Dubbo服务的关键知识点 #### Dubbo框架简介 Dubbo是一款高性能、轻量级的开源微服务框架,由阿里巴巴开源并维护。它主要提供了三大核心能力:面向接口的远程方法调用(Remote Procedure Call,RPC)、...

    dubbo-admin编译后的war包

    本资源为GitHub下载dubbo 资源后打包的dubbo-admin的war包,本地环境默认安装zookeeper后可放到tomcat下直接运行。

    dubbo资源 dubbo-admin dubbo demo

    【标题】"dubbo资源 dubbo-admin dubbo demo" 提供的是关于Apache Dubbo的相关素材,主要包括了Dubbo-admin的管理和示例项目。Dubbo是一个高性能、轻量级的开源Java RPC框架,它提供了丰富的服务治理功能,是阿里...

    最简单的Dubbo案例之二:SpringBoot + dubbo 无zookeeper方式点对点直连

    本项目只适合dubbo入门学习者,高手请不要浪费金钱; 本项目技术栈 springboot, dubbo ,无 zookeeper 本项目旨在提供最单纯的 dubbo 服务提供者 和消费者的点对点直连,而摒弃任何多余技术对dubbo直连的理解

Global site tag (gtag.js) - Google Analytics