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.connectionPoolSize=10 memcached.failureMode=true #server1 server1.memcached.host=127.0.0.1server1.memcached.port=11211server1.memcached.weight=4#server2 server2.memcached.host=127.0.0.1server2.memcached.port=11212server2.memcached.weight=6
我这里是配置两台服务器用以测试,不同的权重。具体文件请访问 https://github.com/mafly/SpringDemo/blob/memcached/src/memcached.properties 查看。
二、在applicationContext.xml
文件中配置
applicationContext.xml
文件,在下面加入 memcached 的配置:
${server1.memcached.host} ${server1.memcached.port} ${server2.memcached.host} ${server2.memcached.port}
${server1.memcached.weight} ${server2.memcached.weight}
这里的地址及端口就是读取刚刚的memcached.properties
配置文件。当然,你不能忘了把配置文件读取到 Spring 容器中管理。
三、建立cn.mayongfa.cache
包,并新增MemcachedBasis.java
基础类
cn.mayongfa.cache
包我就说了,大家都会的,重要的是建完包之后要在applicationContext.xml
文件中配置扫描包,完成 Bean 的注入 。就是下面: 2.新建MemcachedBasis.java
类。
@Componentpublic 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
类
@Componentpublic class UserBasisCache extends MemcachedBasis {private Logger log = Logger.getLogger(UserBasisCache.class);@Autowiredprivate 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
类,实现缓存的增删改查
@Overridepublic long Save(UserBasis entity) { return UserBasisdao.Save(entity);}@Overridepublic Boolean Delete(long ID) { return UserBasisdao.Delete(ID);}@Overridepublic UserBasis getEntity(long ID) { return UserBasisdao.getEntity(ID);}
我们改成了这样的:
@Autowiredprivate UserBasisCache UserBasiscache;@Overridepublic long Save(UserBasis entity) { long id = UserBasisdao.Save(entity); if (id > 0) { UserBasiscache.set(entity); } return id;}@Overridepublic Boolean Delete(long ID) { boolean result = UserBasisdao.Delete(ID); if (result) { UserBasiscache.delete(ID); } return result;}@Overridepublic UserBasis getEntity(long ID) { return UserBasiscache.get(ID);}
看出来区别了吧,就是我们在实现层处理了缓存的操作,并不需要去最外层的调用处处理了。
我讲了整个选择缓存的心路历程,虽然没有干货,但都是值得思考的东西,就有了干货,可以让你用「最原始版」方式来灵活在项目中实现缓存。希望我的分享对你有所帮助吧,所有这些配置及代码都可以在我的 GitHub 上关于 Spring 的示例项目看到:。
又写到凌晨一点,我睡了。