Memcached与Spring集成的方式(待实践)
Posted Jim
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Memcached与Spring集成的方式(待实践)相关的知识,希望对你有一定的参考价值。
主要是基于这几种方式http://www.cnblogs.com/EasonJim/p/7624822.html去实现与Spring集成,而个人建议使用Xmemcached去集成好一些,因为现在官方还在更新,具体参考:https://github.com/killme2008/xmemcached/wiki/Xmemcached%20%E4%B8%AD%E6%96%87%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97
以下方式据说第一种会报错,没测试过。
既然已经使用Spring做集成,那么依赖肯定要使用Maven。
Memcached已经过时了,如果是新项目就不应该侧重选择它,转投Redis。
Memcached Client for Java
<!-- https://mvnrepository.com/artifact/com.whalin/Memcached-Java-Client --> <dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId> <version>3.0.2</version> </dependency>
memcached.properties配置文件:配置服务器地址,连接数,超时时间等
#######################Memcached配置####################### #服务器地址 memcached.server1=127.0.0.1 memcached.port1=11211 #memcached.server=127.0.0.1:11211 #初始化时对每个服务器建立的连接数目 memcached.initConn=20 #每个服务器建立最小的连接数 memcached.minConn=10 #每个服务器建立最大的连接数 memcached.maxConn=50 #自查线程周期进行工作,其每次休眠时间 memcached.maintSleep=3000 #Socket的参数,如果是true在写数据时不缓冲,立即发送出去 memcached.nagle=false #Socket阻塞读取数据的超时时间 memcached.socketTO=3000 ##pool.setServers(servers); ##pool.setWeights(weights); ##pool.setHashingAlg(SockIOPool.CONSISTENT_HASH); ##pool.setInitConn(5); ##pool.setMinConn(5); ##pool.setMaxConn(250); ##pool.setMaxIdle(1000 * 60 * 60 * 6); ##pool.setMaintSleep(30); ##pool.setNagle(false); ##pool.setSocketTO(3000); ##pool.setSocketConnectTO(0);
配置Bean
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- properties config --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="1"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="locations"> <list> <!--<value>classpath:/com/springmvc/config/memcached.properties</value>--> <value>/WEB-INF/config/memcached.properties</value> </list> </property> </bean> <!-- Memcached配置 --> <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool" factory-method="getInstance" init-method="initialize" destroy-method="shutDown"> <property name="servers"> <!-- ${memcached.server} --> <list> <value>${memcached.server1}:${memcached.port1}</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> </bean> </beans>
将app-context-memcached.xml配置到app-context.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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <import resource="app-context-memcached.xml" /><!--memcached 缓存配置 --> <!-- <import resource="app-context-xmemcached.xml" /> --> <!-- <import resource="app-context-spymemcached.xml" /> --> <!-- @Component and @Resource --> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> <!-- 对com包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 --> <context:component-scan base-package="com.springmvc.imooc" /> <!-- 定时器 --> <!-- <task:annotation-driven /> --> <!-- mvc --> <mvc:annotation-driven /> <!-- Aspect --> <!-- <aop:aspectj-autoproxy /> --> </beans>
Memcached工具类:
import java.io.PrintWriter; import java.io.StringWriter; import java.util.Date; import com.danga.MemCached.MemCachedClient; public final class MemcachedUtils {
/** * cachedClient. */ private static MemCachedClient cachedClient; static { if (cachedClient == null) { cachedClient = new MemCachedClient("memcachedPool"); } }
/** * 构造函数. */ private MemcachedUtils() { }
/** * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换. * @param key 键 * @param value 值 * @return boolean */ public static boolean set(String key, Object value) { return setExp(key, value, null); }
/** * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ public static boolean set(String key, Object value, Date expire) { return setExp(key, value, expire); }
/** * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ private static boolean setExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.set(key, value, expire); } catch (Exception e) { MemcachedLog.writeLog("Memcached set方法报错,key值:" + key + "\\r\\n" + exceptionWrite(e)); } return flag; }
/** * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对. * @param key 键 * @param value 值 * @return boolean */ public static boolean add(String key, Object value) { return addExp(key, value, null); }
/** * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ public static boolean add(String key, Object value, Date expire) { return addExp(key, value, expire); }
/** * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ private static boolean addExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.add(key, value, expire); } catch (Exception e) { MemcachedLog.writeLog("Memcached add方法报错,key值:" + key + "\\r\\n" + exceptionWrite(e)); } return flag; }
/** * 仅当键已经存在时,replace 命令才会替换缓存中的键. * @param key 键 * @param value 值 * @return boolean */ public static boolean replace(String key, Object value) { return replaceExp(key, value, null); }
/** * 仅当键已经存在时,replace 命令才会替换缓存中的键. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ public static boolean replace(String key, Object value, Date expire) { return replaceExp(key, value, expire); }
/** * 仅当键已经存在时,replace 命令才会替换缓存中的键. * @param key 键 * @param value 值 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ private static boolean replaceExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.replace(key, value, expire); } catch (Exception e) { MemcachedLog.writeLog("Memcached replace方法报错,key值:" + key + "\\r\\n" + exceptionWrite(e)); } return flag; }
/** * get 命令用于检索与之前添加的键值对相关的值. * @param key 键 * @return boolean */ public static Object get(String key) { Object obj = null; try { obj = cachedClient.get(key); } catch (Exception e) { MemcachedLog.writeLog("Memcached get方法报错,key值:" + key + "\\r\\n" + exceptionWrite(e)); } return obj; }
/** * 删除 memcached 中的任何现有值. * @param key 键 * @return boolean */ public static boolean delete(String key) { return deleteExp(key, null); }
/** * 删除 memcached 中的任何现有值. * @param key 键 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ public static boolean delete(String key, Date expire) { return deleteExp(key, expire); }
/** * 删除 memcached 中的任何现有值. * @param key 键 * @param expire 过期时间 New Date(1000*10):十秒后过期 * @return boolean */ @SuppressWarnings("deprecation") private static boolean deleteExp(String key, Date expire) { boolean flag = false; try { flag = cachedClient.delete(key, expire); } catch (Exception e) { MemcachedLog.writeLog("Memcached delete方法报错,key值:" + key + "\\r\\n" + exceptionWrite(e)); } return flag; }
/** * 清理缓存中的所有键/值对. * @return boolean */ public static boolean flashAll() { boolean flag = false; try { flag = cachedClient.flushAll(); } catch (Exception e) { MemcachedLog.writeLog("Memcached flashAll方法报错\\r\\n" + exceptionWrite(e)); } return flag; }
/** * 返回异常栈信息,String类型. * @param e Exception * @return boolean */ private static String exceptionWrite(Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); pw.flush(); return sw.toString(); } }
测试:
System.out.println(MemcachedUtils.set("aa", "bb", new Date(1000 * 60))); Object obj = MemcachedUtils.get("aa"); System.out.println("***************************"); System.out.println(obj.toString());
SpyMemcached
<!-- https://mvnrepository.com/artifact/net.spy/spymemcached --> <dependency> <groupId>net.spy</groupId> <artifactId>spymemcached</artifactId> <version>2.12.3</version> </dependency>
spymemcached.properties配置文件:
#连接池大小即客户端个数 memcached.connectionPoolSize=1 memcached.failureMode=true #server1 memcached.servers=127.0.0.1:11211 memcached.protocol=BINARY memcached.opTimeout=1000 memcached.timeoutExceptionThreshold=1998 memcached.locatorType=CONSISTENT memcached.failureMode=Redistribute memcached.useNagleAlgorithm=false
app-context-spymemcached.xml配置bean:
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- properties config --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="1"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="locations"> <list> <value>classpath:/com/springmvc/config/spymemcached.properties</value> </list> </property> </bean> <!-- Memcached配置 --> <!-- 枚举类型要想注入到类中,一定要先使用org.springframework.beans.factory.config.FieldRetrievingFactoryBean类将枚举类型进行转换 将DefaultHashAlgorithm.KETAMA_HASH转换为KETAMA_HASH这个bean, 然后在要注入的bean中使用<property name="hashAlg" ref="KETAMA_HASH" />引用即可。 --> <bean id="KETAMA_HASH" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="net.spy.memcached.DefaultHashAlgorithm.KETAMA_HASH" /> </bean> <bean id="memcachedClient" class="net.spy.memcached.spring.MemcachedClientFactoryBean"> <!-- 一个字符串,包括由空格或逗号分隔的主机或IP地址与端口号 --> <property name="servers" value="${memcached.servers}" /> <!-- 指定要使用的协议(BINARY,TEXT),默认是TEXT --> <property name="protocol" value="${memcached.protocol}" /> <!-- 设置默认的转码器(默认以net.spy.memcached.transcoders.SerializingTranscoder) --> <property name="transcoder"> <bean class="net.spy.memcached.transcoders.SerializingTranscoder"> <property name="compressionThreshold" value="1024" /> </bean> </property> <!-- 以毫秒为单位设置默认的操作超时时间 --> <property name="opTimeout" value="${memcached.opTimeout}" /> <property name="timeoutExceptionThreshold" value="${memcached.timeoutExceptionThreshold}" /> <!-- 设置哈希算法 --> <property name="hashAlg" ref="KETAMA_HASH" /> <!-- 设置定位器类型(ARRAY_MOD,CONSISTENT),默认是ARRAY_MOD --> <property name="locatorType" value="${memcached.locatorType}" /> <!-- 设置故障模式(取消,重新分配,重试),默认是重新分配 --> <property name="failureMode" value="${memcached.failureMode}" /> <!-- 想使用Nagle算法,设置为true --> <property name="useNagleAlgorithm" value="${memcached.useNagleAlgorithm}" /> </bean> <bean id="memcachedManager" class="com.springmvc.imooc.util.SpyMemcachedManager"> <property name="memcachedClient" ref="memcachedClient" /> </bean> </beans>
SpyMemcachedManager工具类:
import java.io.IOException; import java.io.OutputStream; import java.net.SocketAddress; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.Future; import net.spy.memcached.ConnectionObserver; import net.spy.memcached.MemcachedClient; import net.spy.memcached.transcoders.Transcoder; public class SpyMemcachedManager {
/** * memcached客户单实例. */ private MemcachedClient memcachedClient;
/** * * TODO 添加方法注释. * * @param obs obs */ public void addObserver(ConnectionObserver obs) { memcachedClient.addObserver(obs); }
/** * * TODO 添加方法注释. * * @param obs obs */ public void removeObserver(ConnectionObserver obs) { memcachedClient.removeObserver(obs); }
/** * * 加入缓存. * * @param key key * @param value value * @param expire 过期时间 * @return boolean */ public 以上是关于Memcached与Spring集成的方式(待实践)的主要内容,如果未能解决你的问题,请参考以下文章Spring集成Jedis(不依赖spring-data-redis)(单机/集群模式)(待实践)
Memcached的Web管理工具MemAdmin(待实践)