原文:https://blog.csdn.net/ggibenben1314/article/details/47752661
緩存的應用非常廣泛,為了提高數據訪問的速度。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,配置緩存
程序入口:
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值是最新的,最近最久不使用的已經被移除了。
