memcached与spring集成
一、背景
销售CRM(项目A)将负责管理项目信息系统(项目B)的支付与权限
上级要求为避免频繁调用CRM接口,中间放一级缓存,但要做到缓存中保证最新数据
因项目B已使用memcache作缓存,所以决定使用memcache
二、设计
1、统一系统交互方式,确保系统与系统间调用只有一个接口,接口参数为(String action, String data),以action区别调用是什么方法
2、封装简单的memcache工具类,可执行简单的增删改查
3、memcache单独一个日志文件,方便查找原因
4、项目A,采用AOP拦截,在对数据进行增删改时,对缓存中数据进行同步操作
5、为项目B再次封装memcache工具类的查询方法,确保在缓存查不到数据时,调用项目A的接口,将数据放于缓存
本文主要讲解memcache与spring的集成,这些设计不在讲解范围内(貌似讲了一堆废话,哈哈)
三、memcache与Spring集成
memcache决定使用memcached client java客户端,原因是其使用较为广泛,单纯求稳妥
在项目/src/main/resources/property下有三个配置文件,分别对应开发环境、预上线、正式线
修改配置文件,增加
#######################设置Memcached服务器参数#######################
#设置服务器地址
memcached.server=172.16.231.230:11211
#容错
memcached.failOver=true
#设置初始连接数
memcached.initConn=20
#设置最小连接数
memcached.minConn=10
#设置最大连接数
memcached.maxConn=250
#设置连接池维护线程的睡眠时间
memcached.maintSleep=3000
#设置是否使用Nagle算法(Socket的参数),如果是true在写数据时不缓冲,立即发送出去
memcached.nagle=false
#设置socket的读取等待超时时间
memcached.socketTO=3000
#设置连接心跳监测开关
memcached.aliveCheck=true
#######################设置Memcached服务器参数#######################
因预上线、与线上环境为封闭环境,memcache服务器地址在不同配置文件中各有不同
可直接在spring的配置文件中增加memcache的配置,在这选择在/src/main/resources中增加memcached-context.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd"> <!-- 加载初始化配置文件
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:property/init.properties</value>
</list>
</property>
</bean>--> <!-- Memcached配置 -->
<bean id="memcachedPool" class="com.whalin.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>
因在spring配置文件中已加载了初始化配置文件,所以在这不需要再加载,如果没有加载过,应放开注释
修改web.xml,增加memcached-content.xml
<!-- spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml,classpath*:memcached-content.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.glodon.gcxx.common.ServletContextInit</listener-class>
</listener>
至此,配完了。。。。 是的,配完了,下面是工具类的代码
package com.glodon.gcxx.Interaction.memcached; import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import com.whalin.MemCached.MemCachedClient;
public class MemcachedUtil {
private static final Logger logger = Logger.getLogger(MemcachedUtil.class);
private static MemCachedClient cachedClient;
static {
if (cachedClient == null)
cachedClient = new MemCachedClient();
} /**
* @Description 添加新的键值对,默认最少使用算法淘汰。如果键已经存在,则之前的值将被替换。
* @author liuy-8
* @date 2015年5月29日 下午2:09:17
* @param key 键
* @param value 值
* @return 是否成功
*/
public static boolean set(String key, Object value) {
return setExp(key, value, null);
} /**
* @Description 添加新的键值对。如果键已经存在,则之前的值将被替换。
* @author liuy-8
* @date 2015年5月29日 下午2:10:08
* @param key 键
* @param value 值
* @param time 过期时间,单位ms
* @return 是否成功
*/
public static boolean set(String key, Object value, int time) {
return setExp(key, value, new Date(time));
} /**
* @Description 添加新的键值对。如果键已经存在,则之前的值将被替换。
* @author liuy-8
* @date 2015年5月29日 下午2:13:18
* @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日志
logger.error("Memcached set方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
}
return flag;
} /**
* @Description 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对,默认最少使用算法淘汰
* @author liuy-8
* @date 2015年5月29日 下午2:13:50
* @param key 键
* @param value 值
* @return 是否成功
*/
public static boolean add(String key, Object value) {
return addExp(key, value, null);
} /**
* @Description 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对
* @author liuy-8
* @date 2015年5月29日 下午2:27:40
* @param key 键
* @param value 值
* @param time 过期时间,单位毫秒
* @return 是否成功
*/
public static boolean add(String key, Object value, int time) {
return addExp(key, value, new Date(time));
} /**
* @Description 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对
* @author liuy-8
* @date 2015年5月29日 下午2:30:29
* @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日志
logger.error("Memcached add方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
}
return flag;
} /**
* @Description 仅当键已经存在时,replace 命令才会替换缓存中的键,默认最少使用算法淘汰
* @author liuy-8
* @date 2015年5月29日 下午2:42:22
* @param key 键
* @param value 值
* @return 是否成功
*/
public static boolean replace(String key, Object value) {
return replaceExp(key, value, null);
} /**
* @Description 仅当键已经存在时,replace 命令才会替换缓存中的键。
* @author liuy-8
* @date 2015年5月29日 下午3:07:51
* @param key 键
* @param value 值
* @param time 过期时间,单位毫秒
* @return 是否成功
*/
public static boolean replace(String key, Object value, int time) {
return replaceExp(key, value, new Date(time));
} /**
* @Description 仅当键已经存在时,replace 命令才会替换缓存中的键。
* @author liuy-8
* @date 2015年5月29日 下午3:09:22
* @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) {
logger.error("Memcached replace方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
}
return flag;
} /**
* @Description 命令用于检索与之前添加的键值对相关的值
* @author liuy-8
* @date 2015年5月29日 下午3:09:45
* @param key 键
* @return 得到与键对应的值
*/
public static Object get(String key) {
Object obj = null;
try {
obj = cachedClient.get(key);
} catch (Exception e) {
logger.error("Memcached get方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
}
return obj;
} /**
* @Description 删除 memcached 中的任何现有值。
* @author liuy-8
* @date 2015年5月29日 下午3:10:57
* @param key 键
* @return 是否成功
*/
public static boolean delete(String key) {
return deleteExp(key, null);
} /**
* @Description 删除 memcached 中的任何现有值。
* @author liuy-8
* @date 2015年5月29日 下午3:33:39
* @param key 键
* @param time 阻塞时间,单位ms,禁止使用同样的键保存新数据,set方法除外
* @return 是否成功
*/
public static boolean delete(String key, int time) {
return deleteExp(key, new Date(time));
} /**
* @Description 方法描述说明
* @author liuy-8
* @date 2015年5月29日 下午3:37:52
* @param key 键
* @param expire 阻塞时间,单位ms,禁止使用同样的键保存新数据,set方法除外
* @return 是否成功
*/
private static boolean deleteExp(String key, Date expire) {
boolean flag = false;
try {
flag = cachedClient.delete(key, expire);
} catch (Exception e) {
logger.error("Memcached delete方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
}
return flag;
} /**
* @Description 清理缓存中的所有键/值对
* @author liuy-8
* @date 2015年5月29日 下午3:38:26
* @return 是否成功
*/
public static boolean flushAll() {
boolean flag = false;
try {
flag = cachedClient.flushAll();
} catch (Exception e) {
logger.error("Memcached flashAll方法报错\r\n" + exceptionWrite(e));
}
return flag;
} /**
* @Description 返回异常栈信息,String类型
* @author liuy-8
* @date 2015年5月29日 下午3:38:52
* @param e 异常
* @return 异常信息
*/
private static String exceptionWrite(Exception e) {
StringWriter sw = null;
PrintWriter pw = null;
String errorInfo = "";
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
errorInfo = sw.toString();
} finally {
//关闭PrintWriter
if(pw != null)
pw.close();
//关闭StringWriter
if(sw != null){
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return errorInfo;
} }
memcached与spring集成的更多相关文章
- Memcached与Spring集成的方式(待实践)
主要是基于这几种方式http://www.cnblogs.com/EasonJim/p/7624822.html去实现与Spring集成,而个人建议使用Xmemcached去集成好一些,因为现在官方还 ...
- Memcached和Spring集成开发
xml配置文件 <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool" facto ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- Memcached理解笔2---XMemcached&Spring集成
一.Memcached Client简要介绍 Memcached Client目前有3种: Memcached Client for Java SpyMemcached XMemcached 这三种C ...
- 160530、memcached集群(spring集成的配置)
第一步:在linux机或windows机上安装memcached服务端(server) linux中安装memcached:centos中命令 yum -y install memcached 如果没 ...
- Memcached笔记——(二)XMemcached&Spring集成
今天研究Memcached的Java的Client,使用XMemcached 1.3.5,做个简单的测试,并介绍如何与Spring集成. 相关链接: Memcached笔记--(一)安装&常规 ...
- Shiro之身份认证、与spring集成(入门级)
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- Spring集成GuavaCache实现本地缓存
Spring集成GuavaCache实现本地缓存: 一.SimpleCacheManager集成GuavaCache 1 package com.bwdz.sp.comm.util.test; 2 3 ...
随机推荐
- UVALive - 6952 DP 分段/隔板
题意:商品总价按四舍五入计算,n个物品最多可分\(d+1\)段,求最小代价 \(dp[i][j]\):\(j\)个物品分\(i\)段 注意一个技巧是只在需要分出新的段时才四舍五入(旧段结算),这样就避 ...
- 转: centos系统home下的中文目录改为英文目录
转自h t t p : / /xugang-1017-126-com.iteye.com/blog/2081845 如果安装了中文版的Cent OS之后,root目录和home目录下会出现中文的路径名 ...
- 集成 Jenkins 和 TestNG 实现自助式自动化测试平台
背景介绍 在软件业十分成熟的今天,敏捷(Agile)开发在业界日益流行,而面临的挑战也日益增多,不断变化的用户需求.缩短的开发周期.频繁的部署上线.复杂的产品架构和团队组织,如何继续保证软件的质量是一 ...
- PIE 支持项目介绍
目前PIE SDK已经支持了气象.海洋.农业.水利.测绘等多个行业应用. [气象应用-和WebGIS程序界面结合] [气象应用-积雪监测] [气象应用-洪涝监测] [气象应用-专题模板] [气象应用- ...
- Django_Xadmin 修改后台
admin组件使用 Django 提供了基于 web页面的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTA ...
- mysql 学习之 DDl语句
mysql 1,登入mysq1: mysql -uroot -p ---->密码隐藏登入好点 2,mysql操作: 创建数据库:create databases test1; 查看数据库:sh ...
- HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分
http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...
- zookeeper 节点信息
使用get命令获取指定节点的数据时, 同时也将返回该节点的状态信息, 称为Stat. 其包含如下字段: czxid. 节点创建时的zxid. mzxid. 节点最新一次更新发生时的zxid. ctim ...
- 【Linux】修改ubuntu默认字符集
今天把以前的项目移植到linux上了,我装的是ubuntu,web服务器是tomcat,发现用freemark模板生成的静态页面全 乱码了,在windows都是正常的,猜想可能是linux字符集的问题 ...
- poi 多行合并
poi做多行合并,一定需要先绘制单元格,然后写入数据,最后合并,不然各种坑啊. 合并单元格所使用的方法: sheet.addMergedRegion( CellRangeAddress cellRa ...