Dubbo之旅--结果缓存

在上篇文章中我们队Dubbo的扩展进行了一些基本了解.这些扩展能够很好的帮助我们在实际的项目中发挥作用,接下来对于dubbo的一些高级特征,针对特殊情况而进行的处理进行进一步的介绍,这里我们要说的是结果缓存.

为什么要用到结果缓存,主要是用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量。

下面我们将通过一个例子来对结果缓存进行一个接触.

1、客户端和服务提供端共用接口类

packagecom.alibaba.dubbo.demo;

public interfaceCacheService {

String findCache(String id);

}

2、服务提供端接口实现类

packagecom.alibaba.dubbo.demo.provider;

importjava.util.concurrent.atomic.AtomicInteger;

importcom.alibaba.dubbo.demo.CacheService;

public classCacheServiceImpl implements CacheService {

//AtomicInteger通过一种线程安全的加减操作接口

private final AtomicInteger i = newAtomicInteger();

@Override

public String findCache(String id) {

String result = "request: " +id + ", response: " + i.getAndIncrement();

System.out.println(result);

return result;

}

}

3、服务提供端配置文件

<?xmlversion="1.0" encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://code.alibabatech.com/schema/dubbo

http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 提供方应用信息,用于计算依赖关系 -->

<dubbo:applicationname="hello-world"  />

<!-- 使用zookeeper注册中心暴露发现服务地址 -->

<dubbo:registryaddress="zookeeper://127.0.0.1:2181" />

<!-- 用dubbo协议在20880端口暴露服务 -->

<dubbo:protocol name="dubbo"port="20880" />

<!-- 声明需要暴露的服务接口 -->

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService"ref="demoService" />

<!-- 和本地bean一样实现服务 -->

<bean id="demoService"class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />

<!-- 声明需要暴露的服务接口 -->

<dubbo:serviceinterface="com.alibaba.dubbo.demo.ValidationService"ref="validationService" />

<!-- 和本地bean一样实现服务 -->

<bean id="validationService"class="com.alibaba.dubbo.demo.provider.ValidationServiceImpl" />

<bean id="cacheService"class="com.alibaba.dubbo.demo.provider.CacheServiceImpl" />

<dubbo:serviceinterface="com.alibaba.dubbo.demo.CacheService"ref="cacheService" />

</beans>

4、客户端配置文件

<?xmlversion="1.0" encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://code.alibabatech.com/schema/dubbo

http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样-->

<dubbo:applicationname="consumer-of-helloworld-app" />

<!-- 使用zookeeper注册中心暴露发现服务地址 -->

<dubbo:registryaddress="zookeeper://127.0.0.1:2181" />

<!-- 生成远程服务代理 -->

<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.demo.DemoService"

retries="2"

/>

<!-- 生成远程服务代理 -->

<dubbo:referenceid="validationService"interface="com.alibaba.dubbo.demo.ValidationService"

retries="2"validation="true"

/>

<!-- 生成远程服务代理 -->

<dubbo:referenceid="cacheService"interface="com.alibaba.dubbo.demo.CacheService"cache="true" />

</beans>

5、客户端主类

importorg.springframework.context.support.ClassPathXmlApplicationContext;

importcom.alibaba.dubbo.demo.CacheService;

public class Consumer {

/**

* @param args

* @throws Exception

*/

public static void main(String[] args)throws Exception {

ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext(

new String[] {"classpath:consumer.xml" });

context.start();

CacheService cacheService =(CacheService) context.getBean("cacheService");

// 测试缓存生效,多次调用返回同样的结果。(服务器端自增长返回值)

String fix = null;

for (int i = 0; i < 5; i++) {

String result =cacheService.findCache("0");

if (fix == null ||fix.equals(result)) {

System.out.println("i=" + i + " OK: " + result);

} else {

System.err.println("i=" + i + " ERROR: " + result);

}

fix = result;

Thread.sleep(500);

}

// LRU的缺省cache.size为1000,执行1001次,应有溢出

for (int n = 0; n < 1001; n++) {

String pre = null;

for (int i = 0; i < 10; i++) {

String result =cacheService.findCache(String.valueOf(n));

if (pre != null &&!pre.equals(result)) {

System.err.println("n=" + n + " ERROR: " + result);

}

pre = result;

}

}

// 测试LRU有移除最开始的一个缓存项

String result =cacheService.findCache("0");

if (fix != null &&!fix.equals(result)) {

System.out.println("OK: "+ result);

} else {

System.err.println("ERROR:" + result);

}

}

}

6、客户端控制台,返回值

i=0 OK: request: 0,response: 0

i=1 OK: request: 0,response: 0

i=2 OK: request: 0,response: 0

i=3 OK: request: 0,response: 0

i=4 OK: request: 0,response: 0

OK: request: 0, response:1001

使用结果缓存的服务方法必须是幂等的,也就是说,相同的输入参数返回相同的结果,参数第一次计算缓存结果,下一次相同参数传入时直接返回结果。

缓存策略有三种:

1、LruCache,lru基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。

2、ThreadLocalCache,threadlocal当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。

3、JCache,jcache与JSR107集成,可以桥接各种缓存实现。

除此之外,我们还可以自定义扩展缓存。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 02:56:11

Dubbo之旅--结果缓存的相关文章

Dubbo之旅--管理控制台

到现在为止我们的Dubbo之旅让我们对Dubbo跟注册中心有了初步的认识,接下来要分享的是Dubbo的管理控制台,在实际的项目中非常的有用,尤其是在dubbo服务提供数量逐渐加大的情况下,通过Dubbo管理控制台能够很好的被我们所用,从而让我们更好的使用Dubbo提供的服务. 首先需要准备Dubbo-Admin管理控制台程序,本人是通过项目的形式将控制台导入Eclipse中,通过Eclipse的方式来启动tomcat服务.当然也可以直接将程序的war包放入Tomcat的webapps中,直接启动

Dubbo之旅--集群容错和负载均衡

当我们的系统中用到Dubbo的集群环境,因为各种原因在集群调用失败时,Dubbo提供了多种容错方案,缺省为failover重试. Dubbo的集群容错在这里想说说他是因为我们实际的项目中出现了此类的问题,因为依赖的第三方项目出现异常,导致dubbo调用超时,此时使用的是默认的集群容错方式,而配置的reties='3',这样前段系统连续掉用了三次服务,结果可想而知. 先说一下各节点关系: 这里的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地

Dubbo之旅--注册中心

在介绍Dubbo的内部逻辑的时候提到很多次注册中心的概念.实现注册中心的有很多,主要是以下四个注册中心分别是: Multicast注册中心 Zookeeper注册中心 Redis注册中心 Simple注册中心 这里将对注册中心的一个实现Zookeeper跟大家分享,因为Zookeeper是应用比较多,也是我们项目中实际用到的注册中心. ZooKeeper 是一个为分布式应用所设计的分布的.开源的协调服务.分布式的应用可以建立在同步.配置管理.分组和命名等服务的更高级别的实现的基础之上. ZooK

Dubbo之旅--扩展注册中心

在上篇文章中我们介绍了关于协议的扩展,并了解扩展它所需要的需求.本篇主要是对注册中心的扩展进行着重的探索. 同样的问题,为什么我们需要去扩展注册中心的?主要有以下三个需求. (1) 多注册中心注册 需求:xx银行有些服务来不及在上海部署,只在北京部署,而上海的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心. consumer.xml <?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns=&qu

Dubbo之旅--问题汇总

在工作和学习的过程中,具体运用Dubbo的时候遇到了很多的问题,这些问题一方面让自己进一步了解所谓的dubbo,另一方面通过对它们的总结和分析能够在工作中加倍的提高效率,接下来将会对遇到的和别人总结的一些常见的问题进行汇总. 1.增加提供服务版本号和消费服务版本号. 这个具体来说不算是一个问题,而是一种问题的解决方案,在我们的实际工作中会面临各种环境资源短缺的问题,也是很实际的问题,刚开始我们还可以提供一个服务进行相关的开发和测试,但是当有多个环境多个版本,多个任务的时候就不满足我们的需求,这时

项目使用dubbo会有提供者缓存问题

问题描述:配置了dubbo提供者,但是老是找到其他配置文件下面zeek地址所在的提供者,有缓存,.dubbo文件中,有一个list列表,原来的提供者缓存还在上面,现在新加的,因为名字没有变,所以追加在后面,加载不到! 在部署项目的 根目录下面 查询隐藏文件  ll -a 命令  .dubbo文件,把这个文件删掉,kill项目进程,重启即可!

Dubbo之旅--架构路线

从自己开始接触Dubbo到现在也有段时间了,在这段时间里,随着项目的不断进行,在项目中也遇到了各种各样的问题,而这些问题和相应的解决方案逐渐加深的对Dubbo有了认识和了解. 先说说什么是Dubbo? 官方的说法是:Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点. 现在我们知道了,Dubbo是阿里巴巴的一个框架,不过自开源后,已有不少其他公司在使用Dubbo,例如:京东,去哪儿,大智

Dubbo之旅--扩展协议

在实际工作中运用dubbo的时候,以上系列的文章基本上能够满足项目的基本需求,当然,对于一些特殊的需求Dubbo可以对其进行扩展,Dubbo拥有者丰富的扩展内容,这次主要将会带领大家去感受一下Dubbo的协议扩展和注册中心扩展. 首先要说的是协议扩展. 为什么要扩展协议呢?什么样的需求需要我们去扩展它? (1) 不同服务不同协议 需求:不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议. consumer.xml <?xmlversion="1.0&qu

Dubbo之旅--内部逻辑

在没有开始用代码来解释之前,用图最能够表达一些关系,关于Dubbo的内部逻辑调用关系,借用官方的图示来说明一下,如下图 通过上图中的一个个方框我们称之为节点,总共有5个节点,这五个节点可以看成五个角色,每个角色都有一定的功能.每个角色的意思如下: Provider: 暴露服务的服务提供方. 在实际项目中一般称这个角色为提供者.它主要是向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销. Consumer: 调用远程服务的服务消费方. 既然有提供者,对应的这就是消费者.服务