由于上一篇有介绍了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); } }
二.Memcached与Spring AOP构建数据库前端缓存框架,并用Maven来管理项目
(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客户端实现分布式缓存的。