Memcached客户端与Spring集成,客户端使用的是Memcached-Java-Client-release_2.6.3

1. 配置Maven

<!-- Memcached client -->  
<dependency>   
    <groupId>com.danga</groupId>  
    <artifactId>memcached-java-client</artifactId>  
    <version>2.6.3</version>  
</dependency> 
public class CacheHelper {
        private static MemCachedClient mcc = new MemCachedClient();
        
        private CacheHelper() {
        }

        static {
            String[] servers = {"71.0.0.29:2222", "71.0.0.29:2223"};
            Integer[] weights = {1, 2};
    
            SockIOPool pool = SockIOPool.getInstance();
    
            pool.setServers(servers);
            pool.setWeights(weights);
            pool.setInitConn(5);
            pool.setMinConn(5);
            pool.setMaxConn(250);
            pool.setMaxIdle(1000 * 60 * 60 * 6);
            pool.setMaintSleep(30);
            pool.setNagle(false); // 禁用nagle算法
            pool.setSocketConnectTO(0);
            pool.setSocketTO(3000); //3秒超时
            pool.setHashingAlg(3);
    
            pool.initialize();
        }

        public static MemCachedClient getMemCachedClient() {
            return  mcc;
        }
    }

测试

MemCachedClient mcc = CacheHelper.getMemCachedClient();
 mcc.add("k8", "1234455");

 MemCachedClient mcc = CacheHelper.getMemCachedClient();
       
        UserModel user = new UserModel("12322222", "lihao", 28);
        boolean is = mcc.add("user2",user);

public void setInitConn( int initConn ) 
设置开始时每个cache服务器的可用连接数

public void setMinConn( int minConn ) 
设置每个服务器最少可用连接数

public void setMaxConn( int maxConn ) 
设置每个服务器最大可用连接数

 public void setMaxIdle( long maxIdle )
  设置可用连接池的最长等待时间

public void setMaintSleep( long maintSleep )
设置连接池维护线程的睡眠时间 ,设置为0,维护线程不启动。维护线程主要通过log输出
socket的运行状况,监测连接数目及空闲等待时间等参数以控制连接创建和关闭。

 public void setNagle( boolean nagle )
设置是否使用Nagle算法,因为我们的通讯数据量通常都比较大(相对TCP控制数据)而且要求响 应及时,因此该值需要设置为false(默认是true)

ublic void setSocketTO( int socketTO ) 
设置socket的读取等待超时值

public void setSocketConnectTO( int socketConnectTO )
 设置socket的连接等待超时值

 public void setHashingAlg( int alg ) 
 设置hash算法
    alg=0 使用String.hashCode()获得hash code,该方法依赖JDK,可能和其他客户端不兼容,建议不使用     
    alg=1 使用original 兼容hash算法,兼容其他客户端
    alg=2 使用CRC32兼容hash算法,兼容其他客户端,性能优于original算法
    alg=3 使用MD5 hash算法
    采用前三种hash算法的时候,查找cache服务器使用余数方法。采用最后一种hash算法查找cache     服务时使用一致性hash方法

public void initialize() 设置完pool参数后最后调用该方法,启动pool。

2.Memcached客户端与Spring集成,客户端使用的是Memcached-Java-Client-release_2.6.3

Properties配置

#######################Memcached配置#######################  
#服务器地址  
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  

Spring配置

<?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:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:util="http://www.springframework.org/schema/util"   
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
           http://www.springframework.org/schema/aop   
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
           http://www.springframework.org/schema/context  
           http://www.springframework.org/schema/context/spring-context-3.0.xsd  
           http://www.springframework.org/schema/util   
           http://www.springframework.org/schema/util/spring-util-3.1.xsd  
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.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: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">  
            <list>  
                <value>${memcached.server}</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>  

Memcached工具类

public class MemcachedUtils {
	private static final Logger logger = Logger.getLogger(MemcachedUtils.class);
	private static MemCachedClient cachedClient;
	static {
		if (cachedClient == null)
			cachedClient = new MemCachedClient();
	}

	private MemcachedUtils() {
	}

	/**
	 * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值
	 * @return
	 */
	public static boolean set(String key, Object value) {
		return setExp(key, value, null);
	}

	/**
	 * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值
	 * @param expire
	 *            过期时间 New Date(1000*10):十秒后过期
	 * @return
	 */
	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
	 */
	private static boolean setExp(String key, Object value, Date expire) {
		boolean flag = false;
		try {
			flag = cachedClient.set(key, value, expire);
		} catch (Exception e) {
			// 记录Memcached日志
			MemcachedLog.writeLog("Memcached set方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
		}
		return flag;
	}

	/**
	 * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值
	 * @return
	 */
	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
	 */
	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
	 */
	private static boolean addExp(String key, Object value, Date expire) {
		boolean flag = false;
		try {
			flag = cachedClient.add(key, value, expire);
		} catch (Exception e) {
			// 记录Memcached日志
			MemcachedLog.writeLog("Memcached add方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
		}
		return flag;
	}

	/**
	 * 仅当键已经存在时,replace 命令才会替换缓存中的键。
	 * 
	 * @param key
	 *            键
	 * @param value
	 *            值
	 * @return
	 */
	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
	 */
	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
	 */
	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
	 */
	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
	 */
	public static boolean delete(String key) {
		return deleteExp(key, null);
	}

	/**
	 * 删除 memcached 中的任何现有值。
	 * 
	 * @param key
	 *            键
	 * @param expire
	 *            过期时间 New Date(1000*10):十秒后过期
	 * @return
	 */
	public static boolean delete(String key, Date expire) {
		return deleteExp(key, expire);
	}

	/**
	 * 删除 memcached 中的任何现有值。
	 * 
	 * @param key
	 *            键
	 * @param expire
	 *            过期时间 New Date(1000*10):十秒后过期
	 * @return
	 */
	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
	 */
	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
	 * @return
	 */
	private static String exceptionWrite(Exception e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);
		pw.flush();
		return sw.toString();
	}

	private static class MemcachedLog {
		private final static String MEMCACHED_LOG = "D:\\memcached.log";
		private final static String LINUX_MEMCACHED_LOG = "/usr/local/logs/memcached.log";
		private static FileWriter fileWriter;
		private static BufferedWriter logWrite;
		// 获取PID,可以找到对应的JVM进程
		private final static RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
		private final static String PID = runtime.getName();

		/**
		 * 初始化写入流
		 */
		static {
			try {
				String osName = System.getProperty("os.name");
				if (osName.indexOf("Windows") == -1) {
					fileWriter = new FileWriter(MEMCACHED_LOG, true);
				} else {
					fileWriter = new FileWriter(LINUX_MEMCACHED_LOG, true);
				}
				logWrite = new BufferedWriter(fileWriter);
			} catch (IOException e) {
				logger.error("memcached 日志初始化失败", e);
				closeLogStream();
			}
		}

		/**
		 * 写入日志信息
		 * 
		 * @param content
		 *            日志内容
		 */
		public static void writeLog(String content) {
			try {
				logWrite.write("[" + PID + "] " + "- [" + DateUtils.formateTime(new Date().getTime()) + "]\r\n"
						+ content);
				logWrite.newLine();
				logWrite.flush();
			} catch (IOException e) {
				logger.error("memcached 写入日志信息失败", e);
			}
		}

		/**
		 * 关闭流
		 */
		private static void closeLogStream() {
			try {
				fileWriter.close();
				logWrite.close();
			} catch (IOException e) {
				logger.error("memcached 日志对象关闭失败", e);
			}
		}
	}
}

使用工具类操作Memcached

@Test  
public void testMemcachedSpring() {  
    MemcachedUtils.set("aa", "bb", new Date(1000 * 60));  
    Object obj = MemcachedUtils.get("aa");  
    System.out.println("***************************");  
    System.out.println(obj.toString());  
}  

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐