Memcached与Spring AOP构建数分布式据库前端缓存框架

  由于上一篇有介绍了Memcached缓存,并集群部署,这边我们就不介绍,我们直接介绍MemcachedSpring AOP构建分布式数据库前端缓存框架

 一.Java 实现Memcached客户端,实现分布式

(1)需要的jar 

     1commons-pool-1.5.6.jar

     2java_memcached-release_2.6.3.jar

     3slf4j-api-1.6.1.jar

     4slf4j-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);
		}
}


二.MemcachedSpring AOP构建数据库前端缓存框架,并用Maven来管理项目

1)我们先温习一下Spring AOP

   AOPAspect Orient Programming)面向切面编程,可以运用在事务管理、安全检查、缓存、对象池管理等。面向切面编程中有一个主要的是Advice,这个Advice定义好的切入点处,连接点之前先执行增强中的代码或者连接点执行后,再执行增强中的代码等。

2)我们用Maven管理SpringMVCjarMemcachedjar

   我们这里就介绍Memcachedjar,在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连接信息的配置和实现

     1global.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 "";
	}
}


5Spring AOPMemcached构建数据库前端缓存框架

     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 AOPMemcached构建数据库前端缓存框架

   

  1)第一次执行我们传参数helloMemcached里面肯定没有,因为是第一次执行,所示从数据库获取对应的值,并保存到Memcached服务端,如图所示:

    

 2)执行第二次,参数是hello,这次没有去操作数据库,直接从Memcached服务端获取对应的值

    

 3)我们这边对Memcached服务端进行集群部署,所以我们查看一下,数据保存到其中的一台,如图所示:



三.构建MemcachedSpring AOP构建数据库前端缓存框架出现的错误

   

 Error:com.schooner.MemCached.SchoonerSockIOPool - attempting to get SockIO from uninitialized pool!


 原因是我们设置MemCachedClientSockIOPoolProxName不一样导致,所以两个名称要一样,如图所示:



四.总结

    我们在上一篇介绍了,Memcached集群部署,有两台memcached.server=192.168.74.129:12000 和memcached.server2=192.168.74.130:13000,我们通过Memcached客户端实现了分布式缓存的,Memcached服务端之间是不能通讯的,所示我们通过Memcached客户端实现分布式缓存的。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。