[Dubbo实战]Dubbo声明式缓存

    缓存的应用非常广泛,为了提高数据访问的速度。Dubbo也不例外,它提供了声明式缓存,以减少用户加缓存的工作量。

一、Dubbo中缓存策略

  • lru 基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
  • threadlocal 当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。
  • jcache 与JSR107集成,可以桥接各种缓存实现。

二、Provider

   服务端包含接口和实现

接口:

package com.tgb.cacheService;

/**
 * 服务端 缓存 接口
 * @author xx
 *
 */
public interface CacheService {
	String findCache(String id);
}

实现:

 

package com.tgb.cacheService;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 服务端 缓存 接口实现
 * @author xx
 *
 */
public class CacheServiceImpl implements CacheService {

	private final AtomicInteger i = new AtomicInteger();
	
	public String findCache(String id) throws Exception {
		 return "request: " + id + ", response: " + i.getAndIncrement();
	}
}

spring配置文件:CacheProvider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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:application name="cache-provider" />
    <dubbo:registry  protocol="zookeeper"  address="192.168.24.140:2181"  />
   	<dubbo:protocol name="dubbo" port="20880" />     
	<dubbo:service interface="com.tgb.cacheService.CacheService" ref="cacheService" />       <!-- 和本地bean一样实现服务 -->
	<bean id="cacheService" class="com.tgb.cacheService.CacheServiceImpl" />
</beans>

程序入口:

package com.tgb.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * 服务端入口
 * @author xx
 *
 */
public class CacheProvider {

	public static void main(String[] args) throws Exception{
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "CacheProvider.xml" });
		context.start();
		System.out.println("按任意键退出");
		System.in.read();
	}
}

三、Consumer

     接口同服务端

spring配置文件:CacheConsumer.xml,配置缓存

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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
        ">     
	<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样  192.9.145.19:2181,192.9.145.19:2182,192.9.145.19:2183-->
	<dubbo:application name="cache-consumer" />       <!-- 使用multicast广播注册中心暴露发现服务地址 -->
	<dubbo:registry  protocol="zookeeper"  address="192.168.24.140:2181" />         <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
	<dubbo:reference id="cacheService" interface="com.tgb.cacheService.CacheService" cache="true" />
</beans>

程序入口:

package com.tgb.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tgb.cacheService.CacheService;

/**
 * 客户端入口
 * @author xx
 *
 */
public class CacheConsumer {

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

	        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "CacheConsumer.xml" });
	        context.start();
	        
	        CacheService cacheService = (CacheService)context.getBean("cacheService");

	        // 测试缓存生效,多次调用返回同样的结果。(服务器端自增长返回值)
	        String fix = null;
	        for (int i = 0; i < 5; i ++) {
	            String result = cacheService.findCache("0"); //request: 0, response: 1001
	            if (fix == null || fix.equals(result)) {
	                System.out.println("OK: " + result);
	            } else {
	                System.err.println("ERROR: " + result);
	            }
	            fix = result;
	            Thread.sleep(6000);
	        }
	        
	        // LRU的缺省cache.size为1000,执行1001次,应有溢出,执行了1001次后1001*2=2002,所以result为2002
	        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("ERROR: " + result);
	                }
	                pre = result;
	            }
	        }
	        
	        // 测试LRU有移除最开始的一个缓存项
	        String result = cacheService.findCache("0"); //request: 0, response: 2002
	        if (fix != null && ! fix.equals(result)) {
	            System.out.println("OK: " + result);
	        } else {
	            System.err.println("ERROR: " + result);
	        }
	    }
	}


三、测试

 首先要启动zookeeper,然后依次启动provider和consumer,执行结果如下:

OK: request: 0, response: 1003
OK: request: 0, response: 1003
OK: request: 0, response: 1003
OK: request: 0, response: 1003
OK: request: 0, response: 1003
OK: request: 0, response: 2004

      服务器端的response值是变化的,但是如果response结果是1000,那么在执行了1001次后,结果为2001,到执行入口中第三个循环的时候缓存中result值是最新的,最近最久不使用的已经被移除了。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值