springboot( 三)redis demo
redis介绍
Redis是目前业界使用最广泛的内存数据存储。相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化。除此之外,Redis还提供一些类数据库的特性,比如事务,HA,主从库。可以说Redis兼具了缓存系统和数据库的一些特性,因此有着丰富的应用场景。本文介绍Redis在Spring Boot中两个典型的应用场景。
如何使用
1、引入 spring-boot-starter-data-redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
2、添加配置文件
#redis配置
# REDIS (RedisProperties)
# Redis服务器地址
spring.redis.host=192.168.31.151
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
#Redis数据库索引(默认为0)
spring.redis.database=0
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
#连接超时时间(毫秒)
spring.redis.timeout=5000
至于redis的安装配置,可见分布式进阶redis,一种安装传统的redis,一种用docker ,建议先安装docker,直接用docker pull redis 比较方便
redisConfig->根据StringRedisTemplate对象命名我们可以知道该对象支持String类型,但是在实际的应用中,我们可能需要存入Object对象。那该怎么存储呢。聪明的你,肯定立刻想到了,直接把对象转成json格式字符串,不就可以存储了嘛。这里我使用jackson依赖转换成json数据
@Configuration
public class RedisConfig { // /**
// * 连接 redis 需要 RedisConnection 和 RedisConnectionFactory,
// * RedisConnection 是通过 RedisConnectionFactory 进行创建
// * RedisConnection 提供较低级的数据操作 (byte arrays)
// */
// @Bean
// RedisConnectionFactory initJedisConnectionFactory(){
// //在这里设置redis连接对象配置
// return new JedisConnectionFactory();
// } /**
* 配置RedisTemplate实例
* @param factory
* @return
*/
@Bean
public RedisTemplate<Serializable, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Serializable, Object> template = new RedisTemplate<Serializable, Object>();
template.setConnectionFactory(connectionFactory);
template.afterPropertiesSet();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new ObjectRedisSerializer());//自定义
//template.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));//redis提供现有的
return template;
}
}
ObjectRedisSerializer类
@Slf4j
public class ObjectRedisSerializer implements RedisSerializer<Object>{ /**
* 定义序列化和发序列化转化类
*/
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter(); /**
* 定义转换空字节数组
*/
private static final byte[] EMPTY_ARRAY = new byte[0]; @Override
public byte[] serialize(Object obj) throws SerializationException {
byte[] byteArray = null;
if (null == obj) {
log.warn("Redis待序列化的对象为空.");
byteArray = EMPTY_ARRAY;
} else {
try {
byteArray = serializer.convert(obj);
} catch (Exception e) {
log.error("Redis序列化对象失败,异常:"+e.getMessage());
byteArray = EMPTY_ARRAY;
}
}
return byteArray;
} @Override
public Object deserialize(byte[] datas) throws SerializationException {
Object obj = null;
if(isNullOrEmpty(datas)){
log.warn("Redis待反序列化的对象为空.");
}else{
try {
obj = deserializer.convert(datas);
} catch (Exception e) {
log.error("Redis反序列化对象失败,异常:"+e.getMessage());
}
}
return obj;
} private boolean isNullOrEmpty(byte[] datas){
return (null == datas)|| (datas.length == 0);
}
}
RedisController
@RestController
@Slf4j
public class RedisController { @Autowired
private IUserService userService; @Autowired
private RedisUtils redisUtils; @Autowired
private RedisTemplate<Serializable, Object> redisTemplate; @RequestMapping("redis/getUser")
public User getUser() throws Exception {
String username = "lisi";
User user = (User) redisTemplate.opsForValue().get("user"+username);
if(user ==null){
log.info("未命中缓存!");
user=userService.findByUsername(username);
redisTemplate.opsForValue().set("user"+username, user);
}
return user;
} @RequestMapping("redis/getUser2")
public User getUser2() throws Exception {
String username = "zhangsan";
User user = (User) redisUtils.get("user"+username);
if(user ==null){
log.info("未命中缓存!");
user=userService.findByUsername(username);
redisUtils.set("user"+username, user);
}
return user;
} }
也可以将常用操作提取出来,封装成RedisUtils,直接使用即可
RedisUtils
@Component
public class RedisUtils { @Autowired
private RedisTemplate<Serializable, Object> redisTemplate; /**
* 读取缓存
*
* @param key
* @return
*/
public Object get(final String key) {
return redisTemplate.opsForValue().get(key);
} /**
* 写入缓存
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
redisTemplate.opsForValue().set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
} /**
* 更新缓存
*/
public boolean getAndSet(final String key, Object value) {
boolean result = false;
try {
redisTemplate.opsForValue().getAndSet(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
} /**
* 删除缓存
*/
public boolean delete(final String key) {
boolean result = false;
try {
redisTemplate.delete(key);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
测试:
发现第一次未走缓存,第二次走了缓存
如果redis获取的User不能强转,即xxx不能转换为xxx,按常理说不通,A怎么不能cast成A呢,debug仔细检查了是否有拼错类名及不一致情况,确实xxx就是xxx,
怎么就不能cast呢?
google一通得知和热部署有关,和用到的spring-boot-devtools有关,和classloader有关,这样就说的通了。看了许多帖子,都是比较直接的解决方案,把spring-boot-devtools注释掉,不要热部署了
共享Session-spring-session-data-redis
分布式系统中,sessiong共享有很多的解决方案,其中托管到缓存中应该是最常用的方案之一,
Spring Session官方说明
Spring Session provides an API and implementations for managing a user’s session information.
如何使用
1、引入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、Session配置: @Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)//失效时间一个月
public class SessionConfig {
}
注意:maxInactiveIntervalInSeconds: 设置Session失效时间,使用Redis Session之后,原Boot的server.session.timeout属性不再生效
redis 客户端 输入 keys '*sessions*'
1) "spring:session:expirations:1591092540000"
2) "spring:session:sessions:expires:88fda400-dc85-4a22-8126-e1858febdc60"
3) "userzhangsan"
4) "spring:session:sessions:88fda400-dc85-4a22-8126-e1858febdc60"
5) "user"
6) "userlisi"
127.0.0.1:6379>
其中 1591092540000为失效时间,意思是这个时间后session失效,88fda400-dc85-4a22-8126-e1858febdc60 为sessionId,登录http://localhost:8080/uid 发现会一致,就说明session 已经在redis里面进行有效的管理了。
如何在两台或者多台中共享session
其实就是按照上面的步骤在另一个项目中再次配置一次,启动后自动就进行了session共享。
代码路径:
springboot( 三)redis demo的更多相关文章
- SpringBoot数据访问(三) SpringBoot整合Redis
前言 除了对关系型数据库的整合支持外,SpringBoot对非关系型数据库也提供了非常好的支持,比如,对Redis的支持. Redis(Remote Dictionary Server,即远程字典服务 ...
- 三:Springboot整合Redis
一:springboot整合redis redis版本:3.0.0 运行环境:linux 1.安装redis 1.1安装gcc yum install gcc-c++ 1.2解压redis.3.0.0 ...
- SpringBoot整合Redis及Redis工具类撰写
SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...
- springboot整合redis——redisTemplate的使用
一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...
- 【springBoot】springBoot集成redis的key,value序列化的相关问题
使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...
- SpringBoot整合Redis、ApachSolr和SpringSession
SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...
- SpringBoot集成redis的key,value序列化的相关问题
使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...
- 带着新人学springboot的应用04(springboot+mybatis+redis 完)
对于缓存也说了比较多了,大家对下图这一堆配置类现在应该有些很粗略的认识了(因为我也就很粗略的认识了一下,哈哈!),咳,那么我们怎么切换这个缓存呢?(就是不用springboot提供的默认的Simple ...
- 28. SpringBoot 集成Redis
1.引入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- SpringBoot使用redis缓存List<Object>
一.概述 最近在做性能优化,之前有一个业务是这样实现的: 1.温度报警后第三方通讯管理机直接把报警信息保存到数据库 2.我们在数据库中添加触发器,(BEFORE INSERT)根据这条报警信息处理业务 ...
随机推荐
- Nacos 服务配置中心
1.因为项目是微服务分布式项目,每个微服务都需要用到配置中心,所以第一步我们先在common中添加相应的依赖 <dependency> <groupId>com.alibaba ...
- CNN可视化技术总结(一)--特征图可视化
导言: 在CV很多方向所谓改进模型,改进网络,都是在按照人的主观思想在改进,常常在说CNN的本质是提取特征,但并不知道它提取了什么特征,哪些区域对于识别真正起作用,也不知道网络是根据什么得出了分类结果 ...
- 使用EFCore连接Oracle数据库时出现的问题
问题 System.TypeLoadException: Method 'Create' in type 'Oracle.EntityFrameworkCore.Infrastructure.Inte ...
- Swagger2配置与使用
Swagger2配置与使用 Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 We ...
- 2、剑指offer-字符串——替换空格
**题目描述** **请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. ...
- LOJ10019生日蛋糕
Mr.W 要制作一个体积为 N*π 的 M 层生日蛋糕,每层都是一个圆柱体. 设从下往上数第 i 蛋糕是半径为 R_i,高度为 H_i 的圆柱.当 i<M 时,要求 R_i>R_{i+1} ...
- HDU1814和平委员会
题目大意: 有n对的人,编号从1-2*n,m对的人之间互相不喜欢,每对人中必徐选1个人加入和平委员会,求字典序最小的解 -------------------------------- 2-SAT问题 ...
- IntelliJ IDEA 20 岁了!20 年前的第 1 版曝光…
IntelliJ IDEA 最近发布了 20 周年庆典: https://www.jetbrains.com/lp/intellijidea-20-anniversary/ IntelliJ IDEA ...
- 通过 JFR 与日志深入探索 JVM - TLAB 原理详解
全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇 什么是 TLAB? TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配 ...
- ElasticSearch 入门简介
公号:码农充电站pro 主页:https://codeshellme.github.io ElasticSearch 是一款强大的.开源的.分布式的搜索与分析引擎,简称 ES,它提供了实时搜索与聚合分 ...