springboot中集成memcached
前言
Memcached 是一个高性能的分布式内存对象缓存系统,其存储性能在某些方面不比redis差,甚至在文本类型数据的存储上性能略优于redis,本文将介绍如何在springboot中集成memcached
准备工作
首先我们需要一款客户端连接对象,类似于我们在使用redis时使用的jedis , 目前memcached主流的客户端是Xmemcached,如果使用的是maven构建项目,则引入对应的依赖
<!--引入memcached-->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.5</version>
</dependency>
配置
memcached在yml(properties)文件的相关配置
# memcached配置
memcached:
server: 1.1.1.1:3333 2.2.2.2:4444 #memcached服务器集群(格式为host:port,多个服务器之间用空格隔开)
opTimeout: 3000 #接口操作的默认超时时间,可以被接口覆盖
poolSize: 10 #池子大小
failureMode: false #是否开启失败模式,默认为false
enabled: true # 是否使用memcached缓存
将memcached的配置由bean来管理,方便我们调用
package com.me.config.properties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; /**
* @author : wang zns
* @date : 2018-12-19
*/
@Component
@ConfigurationProperties(prefix = "memcached")
public class MemcachedProperties { /**
* 服务器
*/
private String server; /**
* 操作超时时间,可以被API覆盖
*/
private Integer opTimeout;
/**
* 连接池大小
*/
private Integer poolSize; /**
* 是否开启失败模式
*/
private boolean failureMode; /**
* 是否使用memcached缓存
*/
private boolean enabled; public String getServer() {
return server;
} public void setServer(String server) {
this.server = server;
} public Integer getOpTimeout() {
return opTimeout;
} public void setOpTimeout(Integer opTimeout) {
this.opTimeout = opTimeout;
} public Integer getPoolSize() {
return poolSize;
} public void setPoolSize(Integer poolSize) {
this.poolSize = poolSize;
} public boolean isFailureMode() {
return failureMode;
} public void setFailureMode(boolean failureMode) {
this.failureMode = failureMode;
} public boolean isEnabled() {
return enabled;
} public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
memcached配置类(创建memcached客户端对象,并注入spring容器中)
package com.me.config; import cn.stylefeng.guns.config.properties.MemcachedProperties;
import lombok.extern.slf4j.Slf4j;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author : wang zns
* @date : 2018-12-19
*/
@Configuration
@Slf4j
public class MemcachedConfig { @Autowired
private MemcachedProperties memcachedProperties; @Bean(name = "memcachedClientBuilder")
public MemcachedClientBuilder getBuilder() {
MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder(memcachedProperties.getServer()); // 内部采用一致性哈希算法
memcachedClientBuilder.setSessionLocator(new KetamaMemcachedSessionLocator());
// 操作的超时时间
memcachedClientBuilder.setOpTimeout(memcachedProperties.getOpTimeout());
// 采用二进制传输协议(默认为文本协议)
memcachedClientBuilder.setCommandFactory(new BinaryCommandFactory());
// 设置连接池的大小
memcachedClientBuilder.setConnectionPoolSize(memcachedProperties.getPoolSize());
// 是否开起失败模式
memcachedClientBuilder.setFailureMode(memcachedProperties.isFailureMode());
return memcachedClientBuilder;
} /**
* 由Builder创建memcachedClient对象,并注入spring容器中
* @param memcachedClientBuilder
* @return
*/
@Bean(name = "memcachedClient")
public MemcachedClient getClient(@Qualifier("memcachedClientBuilder") MemcachedClientBuilder memcachedClientBuilder) {
MemcachedClient client = null;
try {
client = memcachedClientBuilder.build();
} catch(Exception e) {
log.info("exception happens when bulid memcached client{}",e.toString());
}
return client;
} }
使用
有了client对象之后,我们可以像直接操作服务端那样进行对应的操作,下面用一个小案例进行演示
service
package cn.stylefeng.guns.modular.housemanage.cache; import cn.stylefeng.guns.modular.system.model.TblHouse; /**
* 房屋管理缓存 业务层
* @author : wang zns
* @date : 2018-12-19
*/
public interface HouseManageCacheService { /**
* 添加
* @param tblHouse
*/
void add(TblHouse tblHouse); /**
* 根据主键删除
* @param tblHouseId
*/
void delete(Integer tblHouseId); }
serviceImpl
package cn.stylefeng.guns.modular.housemanage.cache; import cn.stylefeng.guns.modular.housemanage.service.ITblHouseService;
import cn.stylefeng.guns.modular.system.model.TblHouse;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.rubyeye.xmemcached.MemcachedClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; /**
* @author : wang zns
* @date : 2018-12-19
*/
@Service
@Slf4j
public class HouseManageCacheServiceImpl implements HouseManageCacheService{ @Autowired
private MemcachedClient memcachedClient;
@Autowired
private ITblHouseService iTblHouseService; @Override
public void add(TblHouse tblHouse) {
// 先入库,入库成功则入缓存
boolean isSuccess = iTblHouseService.insert(tblHouse);
if (isSuccess) {
try {
String houseJsonStr = JSON.toJSONString(tblHouse);
memcachedClient.set(String.valueOf(tblHouse.getId()),0,houseJsonStr);
} catch (Exception e) {
log.info("exception happens when add House:{}",e.toString());
throw new RuntimeException(e.getMessage());
}
}
} @Override
public void delete(Integer tblHouseId) {
// 先删除数据库内容,成功则清空缓存
boolean isSuccess = iTblHouseService.deleteById(tblHouseId);
if (isSuccess) {
try {
memcachedClient.delete(String.valueOf(tblHouseId));
} catch (Exception e) {
log.info("exception happens when delete House:{}",e.toString());
throw new RuntimeException(e.getMessage());
}
}
} }
controller
/**
* 新增房屋管理
*/
@RequestMapping(value = "/add")
@ResponseBody
public Object add(@Valid TblHouse tblHouse, BindingResult bindingResult) {
if(bindingResult.hasErrors()){
throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
}
// 如果确定要使用缓存
if (memcachedProperties.isEnabled()) {
houseManageCacheService.add(tblHouse);
} else {
tblHouseService.insert(tblHouse);
}
return SUCCESS_TIP;
} /**
* 删除房屋管理
*/
@RequestMapping(value = "/delete")
@ResponseBody
public Object delete(@RequestParam Integer tblHouseId) {
if (memcachedProperties.isEnabled()) {
houseManageCacheService.delete(tblHouseId);
} else {
tblHouseService.deleteById(tblHouseId);
}
return SUCCESS_TIP;
}
运行结果:

提交之后,去缓存服务器上查看

至此,springboot中集成memcached就完成了
写在最后
springboot集成memcached非常简单,核心步骤就是添加依赖、创建client对象并注入spring容器、然后就是用client对象进行各种操作。
client的接口当然有非常多,xmemcached对接口进行了封装。
最后附上xmemcached官网的地址,里面的文档很详细 https://github.com/killme2008/xmemcached/wiki
springboot中集成memcached的更多相关文章
- Discuz!NT中集成Memcached分布式缓存
大约在两年前我写过一篇关于Discuz!NT缓存架构的文章,在那篇文章的结尾介绍了在IIS中如果开启多个应用程序池会造成多个缓存实例之间数据同步的问题.虽然给出了一个解决方案,但无形中却把压力转移到了 ...
- 在springboot中集成mybatis开发
在springboot中利用mybatis框架进行开发需要集成mybatis才能进行开发,那么如何在springboot中集成mybatis呢?按照以下几个步骤就可以实现springboot集成myb ...
- 在springboot中集成jsp开发
springboot就是一个升级版的spring.它可以极大的简化xml配置文件,可以采用全注解形式开发,一个字就是很牛.在springboot想要使用jsp开发,需要集成jsp,在springboo ...
- SpringBoot中集成redis
转载:https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html 不是使用注解而是代码调用 需要在springbo ...
- SpringBoot中集成Swagger2
1.依赖jar <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-s ...
- 如何在SpringBoot中集成JWT(JSON Web Token)鉴权
这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...
- springboot 中 集成druid ,redis
1,导入druid jar包 <!--引入drud--> <dependency> <groupId>com.alibaba</groupId> < ...
- 使用Logstash同步数据至Elasticsearch,Spring Boot中集成Elasticsearch实现搜索
安装logstash.同步数据至ElasticSearch 为什么使用logstash来同步,CSDN上有一篇文章简要的分析了以下几种同步工具的优缺点:https://blog.csdn.net/la ...
- springboot中使用spring-session实现共享会话到redis(二)
上篇文章介绍了springboot中集成spring-session实现了将session分布式存到redis中.这篇在深入介绍一些spring-session的细节. 1.session超时: 在t ...
随机推荐
- 「JOI 2017 Final」绳
题意 loj 做法 首先我们观察到最后能折起来的充要条件是: 只有两个颜色,除首尾外,所有颜色块内的数量为偶数 因为为偶数,我们进一步推论: 所有颜色块起始位置奇偶性相同 然后因为增与减都会有相同花费 ...
- VS2019 backspace键失效,无法使用
原因:据网上其他资源了解,可能是和其它的快捷键冲突了,但是我这边没有设置快捷键,突然就这样了,出现原因不详,有了解的伙伴可以留言学习一下. 解决方法:工具=>设置=>键盘=>点击重置
- 理财收益的计算 计算浮点数的n次方 1466
题目描述 老傻非常喜欢购买理财产品,而且这款理财产品被推销人员吹得特别高,对于贪财的老傻来说正中下怀,于是在心里盘算着买了它,自己就是亿万富豪,现需要你编写一个程序,帮老傻计算其收益,老傻的投入是R( ...
- Python第三方库requests的编码问题
PS:这个解决方法可能很简单,但是这是平时的一些细节问题,所以有必要提醒一下! 首先代码不多,就是通过get方法去获取豆瓣首页信息,如图:但是会报UnicodeEncodeError: 'gbk' c ...
- 纪中5日T2 1565. 神秘山庄
1565. 神秘山庄 (Standard IO) 原题 题目描述 翠亨村是一个神秘的山庄,并不是因为它孕育了伟人孙中山,更神秘的是山庄里有N只鬼.M只兔子,当然还有你.其中每秒钟: 1. 恰有两个生物 ...
- .net mvc 使用 aspose.cells导出数据
public class AsposeCellsHelper { public Workbook workBook; public Worksheet worksheet; Style style; ...
- 使用Dockerfile构建镜像命令自己的理解
1.FROM 基于那个基础命令开始构建镜像,我的理解就是选择一个操作系统 2.CMD 里面放的是指定一个容器启动时要运行的命令 3.ENTRYPOINT 类似于CDM命令,不过 docker run ...
- ROS开发--在订阅话题的回调函数中发布话题
处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...
- Python之旅第五天(习题集合)
4天时间,虽然上着班,但是学的东西还是有点多,而且晚上看的比较容易忘,所以今天是习题模式,正好教程也是这么要求的,本来以为时间不长,没想到还是很崩溃啊.不多说,上干货. #关于随机产生验证码同时验证用 ...
- 其他 - PotPlayer - 基础快捷键总结
概述 尝试使用 potplayer 的快捷键 背景 最近需要反复看录像 回看 慢速 其他各种 没错, 我的需求就是 游戏复盘... 环境 os win10.1903 player potplayer. ...