Memcached 客户端选择

上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个:

  • Memcached Client for Java
  • SpyMemcached
  • XMemcached

他们的对比与性能我这里不讨论,想了解自己搜索查看,我这里使用的是 XMemcached ,据说它的并发效果更好一些。

地址:https://github.com/killme2008/xmemcached

一些基础的准备

首先,你要下载一个 memcached 服务端安装一下,这是他的网址:https://github.com/memcached/memcached/wiki/ReleaseNotes,如果是 Windows 系统,自己去找安装包安装一下即可。启动服务。

然后,你需要一个 xmemcached.jar 包,你可以直接通过我GitHub上的示例项目直接获取到,我贴一个地址:https://github.com/mafly/SpringDemo/blob/master/WebContent/WEB-INF/lib/xmemcached-1.3.8.jar

开试写代码吧

一、在src目录下建立memcached.properties配置文件

这个文件是用来存 memcached 服务器的地址、端口和权重的信息的

memcached.connectionPoolSize=10
memcached.failureMode=true #server1
server1.memcached.host=127.0.0.1
server1.memcached.port=11211
server1.memcached.weight=4 #server2
server2.memcached.host=127.0.0.1
server2.memcached.port=11212
server2.memcached.weight=6

我这里是配置两台服务器用以测试,不同的权重。具体文件请访问 https://github.com/mafly/SpringDemo/blob/memcached/src/memcached.properties 查看。

二、在applicationContext.xml文件中配置

打开applicationContext.xml文件,在下面加入 memcached 的配置:

<!-- Memcached 配置 -->
<bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder"
p:connectionPoolSize="${memcached.connectionPoolSize}" p:failureMode="${memcached.failureMode}">
<!-- XMemcachedClientBuilder have two arguments.First is server list,and second is weights array. -->
<constructor-arg>
<list>
<bean class="java.net.InetSocketAddress">
<constructor-arg>
<value>${server1.memcached.host}</value>
</constructor-arg>
<constructor-arg>
<value>${server1.memcached.port}</value>
</constructor-arg>
</bean>
<bean class="java.net.InetSocketAddress">
<constructor-arg>
<value>${server2.memcached.host}</value>
</constructor-arg>
<constructor-arg>
<value>${server2.memcached.port}</value>
</constructor-arg>
</bean>
</list>
</constructor-arg>
<constructor-arg>
<list>
<value>${server1.memcached.weight}</value>
<value>${server2.memcached.weight}</value>
</list>
</constructor-arg>
<property name="commandFactory">
<bean class="net.rubyeye.xmemcached.command.TextCommandFactory" />
</property>
<property name="sessionLocator">
<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator" />
</property>
<property name="transcoder">
<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
</property>
</bean>
<!-- Use factory bean to build memcached client -->
<bean id="memcachedClient" factory-bean="memcachedClientBuilder"
factory-method="build" destroy-method="shutdown" />

这里的地址及端口就是读取刚刚的memcached.properties配置文件。当然,你不能忘了把配置文件读取到 Spring 容器中管理。

三、建立cn.mayongfa.cache包,并新增MemcachedBasis.java基础类

1.新建cn.mayongfa.cache包我就说了,大家都会的,重要的是建完包之后要在applicationContext.xml文件中配置扫描包,完成 Bean 的注入 。就是下面:

	<context:component-scan base-package="cn.mayongfa.cache" />

2.新建MemcachedBasis.java类。

@Component
public class MemcachedBasis { @Autowired
protected MemcachedClient memcachedClient; /**
* 失效时间(秒)3600*24 一天
*/
protected int Exptime = 3600 * 24; /**
* 基础数据失效时间(秒)3600*24*7 一周
*/
protected int DataExptime = this.Exptime * 7; protected String Prefix = "SPRINGDEMO:";
}

都是我们需要用的基本信息,就是一个基类的概念,主要用于其他缓存类继承它,就不需要重复定义这些变量了。

四、新增UserBasisCache.java缓存类,继承于MemcachedBasis.java

@Component
public class UserBasisCache extends MemcachedBasis { private Logger log = Logger.getLogger(UserBasisCache.class);
@Autowired
private UserBasisDao userBasisDao; /**
* 设置缓存
*
* @param model
* 用户model
* @return
*/
public Boolean set(UserBasis model) {
Boolean result = false;
try {
result = memcachedClient.set(getCacheKey(model.getId()), super.Exptime, model);
} catch (TimeoutException | InterruptedException | MemcachedException e) {
log.error("", e);
}
return result;
} /**
* 获取缓存
*
* @param id
* 用户ID
* @return
*/
public UserBasis get(long id) {
UserBasis entity = new UserBasis();
try {
entity = memcachedClient.get(getCacheKey(id));
if (entity == null || entity.getId() <= 0) {
entity = userBasisDao.getEntity(id);
this.set(entity);
}
} catch (TimeoutException | InterruptedException | MemcachedException e) {
log.error("", e);
entity = userBasisDao.getEntity(id);
}
return entity;
} /**
* 删除缓存
*
* @param id
* 用户ID
* @return
*/
public Boolean delete(long id) {
try {
return memcachedClient.delete(getCacheKey(id));
} catch (TimeoutException | InterruptedException | MemcachedException e) {
log.error("", e);
}
return false;
} /**
* 获取缓存 Key
*
* @param id
* 用户ID
* @return
*/
private String getCacheKey(long id) {
return super.Prefix + "UserBasis:" + id;
}
}

这个就是具体的业务逻辑的缓存的获取、增加、修改和删除的处理了,这里是以每个用户来添加到缓存,只是用来演示的,具体的情况你们自己处理。

还记不记得上篇文章说:我们怎么做到缓存对代码的侵入性,以及我们怎么更方便或者说不需要改代码就实现缓存。 其实这个时候,我们会发现我们项目架构是分层的,分层的意义不就是为了分配职责、减小耦合和定义标准嘛。那这个时候我们如果都在实现层(Service.Imp)来实现缓存的增删改查,那是不是 Controller 层的调用就不需要任何改动了,也不需要考虑缓存怎么实现的了,不需要去执行缓存的增删改查了,还是像原来那样直接调用实现层的方法就行了。

五、修改UserBasisServiceImp.java类,实现缓存的增删改查

最开始这个类其中的方法是这样的:

@Override
public long Save(UserBasis entity) {
return UserBasisdao.Save(entity);
} @Override
public Boolean Delete(long ID) {
return UserBasisdao.Delete(ID);
} @Override
public UserBasis getEntity(long ID) {
return UserBasisdao.getEntity(ID);
}

我们改成了这样的:

@Autowired
private UserBasisCache UserBasiscache; @Override
public long Save(UserBasis entity) {
long id = UserBasisdao.Save(entity);
if (id > 0) {
UserBasiscache.set(entity);
}
return id;
} @Override
public Boolean Delete(long ID) {
boolean result = UserBasisdao.Delete(ID);
if (result) {
UserBasiscache.delete(ID);
}
return result;
} @Override
public UserBasis getEntity(long ID) {
return UserBasiscache.get(ID);
}

看出来区别了吧,就是我们在实现层处理了缓存的操作,并不需要去最外层的调用处处理了。

总结一下

上一篇文章我讲了整个选择缓存的心路历程,虽然没有干货,但都是值得思考的东西,这篇文章就有了干货,可以让你用「最原始版」方式来灵活在项目中实现缓存。希望我的分享对你有所帮助吧,所有这些配置及代码都可以在我的 GitHub 上关于 Spring 的示例项目看到:https://github.com/mafly/SpringDemo/tree/memcached

又写到凌晨一点,我睡了。

从零开始学 Java - Spring 集成 Memcached 缓存配置(二)的更多相关文章

  1. 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)

    硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...

  2. 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)

    从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...

  3. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  4. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  5. 从零开始学 Java - Spring 支持 CORS 请求踩的坑

    谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...

  6. 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求

    论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...

  7. 从零开始学 Java - Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...

  8. 从零开始学 Java - Spring 一主多从、多主多从 数据库配置

    待会苹果要开发布会 我写完这篇文章就准备去看发布会了,因为我买了好几包瓜子和啤酒.由于苹果的保密做的越来越差劲,该曝光的信息差不多全部曝光了,我们这种熬夜看发布会的只不过是让这些信息更加真实,或者说是 ...

  9. 从零开始学 Java - Spring 使用 Quartz 任务调度定时器

    生活的味道 睁开眼看一看窗外的阳光,伸一个懒腰,拿起放在床一旁的水白开水,甜甜的味道,晃着尾巴东张西望的猫猫,在窗台上舞蹈.你向生活微笑,生活也向你微笑. 请你不要询问我的未来,这有些可笑.你问我你是 ...

随机推荐

  1. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  2. react-redux

    1. 首先redux,与react是两个独立的个体,项目中可以只用react,也可以只用redux 1.1 react-redux: 是一个redux作者专门为react制作的 redux, 增加了新 ...

  3. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. javascript设计模式:策略模式

    前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...

  5. js callee,caller学习

    原文地址:js callee,caller学习 /* * caller 返回一个对函数的引用,该函数调用了当前函数. * 如果函数是由顶层调用的,那么 caller包含的就是 null . * 如果在 ...

  6. 如何使用本地账户"完整"安装 SharePoint Server 2010+解决“New-SPConfigurationDatabase : 无法连接到 SharePoint_Config 的 SQL Server 的数据 库 master。此数据库可能不存在,或当前用户没有连接权限。”

    注:目前看到的解决本地账户完整安装SharePoint Server 2010的解决方案如下,但是,有但是的哦: 当我们选择了"完整"模式安装SharePointServer201 ...

  7. AFN解析器里的坑

    AFN框架是用来用来发送网络请求的,它的好处是可以自动给你解析JSON数据,还可以发送带参数的请求AFN框架还可以监测当前的网络状态,还支持HTTPS请求,分别对用的类为AFNetworkReacha ...

  8. CentOS:设置系统级代理(转)

    原文地址:http://www.cnblogs.com/cocowool/archive/2012/07/05/2578487.html YUM代理设置 编辑/etc/yum.conf,在最后加入 # ...

  9. Jquery双向select控件Bootstrap Dual Listbox

    效果预览: 一. 下载插件 github地址:https://github.com/istvan-ujjmeszaros/bootstrap-duallistbox 也可以在这个网站中下载:http: ...

  10. 更有效率的使用Visual Studio(二)

    没想到上一篇文章有这么多人喜欢,多谢大家支持.继续- 很多比较通用的快捷键的默认设置其实是有一些缩写在里面的,这个估计也是MS帮助我们记忆.比如说注释代码的快捷键是Ctrl + E + C,我们如果知 ...