由于上一篇有介绍了Memcached缓存,并集群部署,这边我们就不介绍,我们直接介绍Memcached与Spring AOP构建分布式数据库前端缓存框架
一.Java 实现Memcached客户端,实现分布式
(1)需要的jar
1)commons-pool-1.5.6.jar
2)java_memcached-release_2.6.3.jar
3)slf4j-api-1.6.1.jar
4)slf4j-simple-1.6.1.jar
(2)Java 实现Memcached客户端代码如下:
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class TestCache {
/**
* @param args
*/
public static void main(String[] args) {
String[] servers = { "192.168.74.129:12000,192.168.74.130:13000"};
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);
pool.setFailover(true);
pool.setInitConn(10);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setAliveCheck(true);
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient();
boolean success = memCachedClient.set("zcy", "dataValue");
System.out.println(success);
Object obj= memCachedClient.get("zcy");
System.out.println(obj);
}
}
(1)我们先温习一下Spring AOP
AOP(Aspect Orient Programming)面向切面编程,可以运用在事务管理、安全检查、缓存、对象池管理等。面向切面编程中有一个主要的是Advice,这个Advice定义好的切入点处,连接点之前先执行增强中的代码或者连接点执行后,再执行增强中的代码等。
(2)我们用Maven管理SpringMVC的jar和Memcached的jar
我们这里就介绍Memcached的jar,在POM.XML中添加Memcached对应的jar包
<dependency>
<groupId>com.danga</groupId>
<artifactId>java-memcached</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
(3)用Spring来管理Memcached连接信息的配置和实现
1)global.properties 文件
#服务器地址
memcached.server=192.168.74.129:12000
memcached.server2=192.168.74.130:13000
#初始化时对每个服务器建立的连接数目
memcached.initConn=20
#每个服务器建立最小的连接数
memcached.minConn=10
#每个服务器建立最大的连接数
memcached.maxConn=50
#自查线程周期进行工作,其每次休眠时间
memcached.maintSleep=3000
#Socket的参数,如果是true在写数据时不缓冲,立即发送出去
memcached.nagle=false
#Socket阻塞读取数据的超时时间
memcached.socketTO=3000
memcached.aliveCheck=true
memcached.failover=true
2)Spring配置文件(applicationContext-memached.xml)
<!-- 注入属性文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:global.properties</value>
</list>
</property>
</bean>
<bean id="memCachedPool" class="com.danga.MemCached.SockIOPool" factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
<constructor-arg>
<value>memcachedPool</value>
</constructor-arg>
<property name="servers">
<list>
<value>${memcached.server}</value>
<value>${memcached.server2}</value>
</list>
</property>
<property name="initConn">
<value>${memcached.initConn}</value>
</property>
<property name="minConn">
<value>${memcached.minConn}</value>
</property>
<property name="maxConn">
<value>${memcached.maxConn}</value>
</property>
<property name="maintSleep">
<value>${memcached.maintSleep}</value>
</property>
<property name="nagle">
<value>${memcached.nagle}</value>
</property>
<property name="socketTO">
<value>${memcached.socketTO}</value>
</property>
<property name="aliveCheck">
<value>${memcached.aliveCheck}</value>
</property>
<property name="failover">
<value>${memcached.failover}</value>
</property>
</bean>
<bean id="memCachedClient" class="com.danga.MemCached.MemCachedClient">
<constructor-arg>
<span style="color:#ff0000;"><value>memcachedPool</value></span>
</constructor-arg>
</bean>
3)junit测试一下这样配置是否正确,代码如下:
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.danga.MemCached.MemCachedClient;
public class MemcachedServiceTest
{
private MemCachedClient memCachedClient;
@Before
public void beforeTest(){
ApplicationContext atx = new ClassPathXmlApplicationContext("classpath:applicationContext-memached.xml");
memCachedClient = (MemCachedClient)atx.getBean("memCachedClient");
}
@Test
public void memCached()
{
boolean b=memCachedClient.set("hello","dataValue");
System.out.println(b);
Object obj=memCachedClient.get("hello");
System.out.println(obj);
}
}
能保存并能获取数据说明配置成功
(4)实现MVC业务逻辑
//Dao层
@Service("dataDao")
public class DataDaoImpl implements DataDao {
@Override
public String getData(String name) {
return name+" get data";
}
}
//server层
@Service("dataService")
public class DataServiceImpl implements DataService{
@Autowired
private DataDao dataDao;
public String findDataByParams(String name) {
return dataDao.getData(name);
}
}
//Controller层
@Controller
public class IndexController {
@Autowired
private DataService dataService;
@RequestMapping("/index")
public String index(Model model,@RequestParam(value="name") String name){
String dataValue=dataService.findDataByParams(name);
System.out.println(dataValue);
return "";
}
}
(5)Spring AOP与Memcached构建数据库前端缓存框架
1)实现AOP的逻辑代码
@Service("dataInterceptor")
public class DataInterceptor implements MethodInterceptor{
@Autowired
private MemCachedClient memCachedClient;
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object[] args = invocation.getArguments();
String param=args[0].toString();
Object object = null;
if(param!=null&&memCachedClient!=null){
object=memCachedClient.get(param);
System.out.println("执行从MemCached获取的值======="+object);
}
if(object==null){
object =invocation.proceed();
System.out.println("执行数据库操作获取的值======="+object);
if (object != null) {
boolean b=memCachedClient.set(param,object);
if(b){
System.out.println("=====保存值"+object+"到memCached 成功===========");
}else{
System.out.println("=====保存值"+object+"到memCached 失败===========");
}
}
System.out.println("没有从memCached获取===========");
}else{
System.out.println("从memCached获取======="+object);
}
return object;
}
}
2)Spring 配置文件配置AOP
<bean id="dataInterceptorAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedName"><value>getData</value></property>
<property name="advice" ref="dataInterceptor"/>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="dataDao"/>
<property name="interceptorNames" value="dataInterceptorAdvisor"/>
</bean>
配置了对哪个方法进行拦截,这里我们对getData方法进行拦截
(6)测试Spring AOP与Memcached构建数据库前端缓存框架
1)第一次执行我们传参数hello,Memcached里面肯定没有,因为是第一次执行,所示从数据库获取对应的值,并保存到Memcached服务端,如图所示:
2)执行第二次,参数是hello,这次没有去操作数据库,直接从Memcached服务端获取对应的值
3)我们这边对Memcached服务端进行集群部署,所以我们查看一下,数据保存到其中的一台,如图所示:
三.构建Memcached与Spring AOP构建数据库前端缓存框架出现的错误
Error:com.schooner.MemCached.SchoonerSockIOPool - attempting to get SockIO from uninitialized pool!
原因是我们设置MemCachedClient和SockIOPool的ProxName不一样导致,所以两个名称要一样,如图所示:
四.总结
我们在上一篇介绍了,Memcached集群部署,有两台memcached.server=192.168.74.129:12000 和memcached.server2=192.168.74.130:13000,我们通过Memcached客户端实现了分布式缓存的,Memcached服务端之间是不能通讯的,所示我们通过Memcached客户端实现分布式缓存的。