本文共 7073 字,大约阅读时间需要 23 分钟。
由于上一篇有介绍了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 {
-
-
-
-
- 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业务逻辑
-
- @Service("dataDao")
- public class DataDaoImpl implements DataDao {
- @Override
- public String getData(String name) {
- return name+" get data";
- }
- }
-
-
- @Service("dataService")
- public class DataServiceImpl implements DataService{
- @Autowired
- private DataDao dataDao;
- public String findDataByParams(String name) {
-
- return dataDao.getData(name);
- }
- }
-
- @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客户端实现分布式缓存的。