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的更多相关文章

  1. SpringBoot数据访问(三) SpringBoot整合Redis

    前言 除了对关系型数据库的整合支持外,SpringBoot对非关系型数据库也提供了非常好的支持,比如,对Redis的支持. Redis(Remote Dictionary Server,即远程字典服务 ...

  2. 三:Springboot整合Redis

    一:springboot整合redis redis版本:3.0.0 运行环境:linux 1.安装redis 1.1安装gcc yum install gcc-c++ 1.2解压redis.3.0.0 ...

  3. SpringBoot整合Redis及Redis工具类撰写

            SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...

  4. springboot整合redis——redisTemplate的使用

    一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...

  5. 【springBoot】springBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  6. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  7. SpringBoot集成redis的key,value序列化的相关问题

    使用的是maven工程 springBoot集成redis默认使用的是注解,在官方文档中只需要2步; 1.在pom文件中引入即可 <dependency> <groupId>o ...

  8. 带着新人学springboot的应用04(springboot+mybatis+redis 完)

    对于缓存也说了比较多了,大家对下图这一堆配置类现在应该有些很粗略的认识了(因为我也就很粗略的认识了一下,哈哈!),咳,那么我们怎么切换这个缓存呢?(就是不用springboot提供的默认的Simple ...

  9. 28. SpringBoot 集成Redis

    1.引入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  10. SpringBoot使用redis缓存List<Object>

    一.概述 最近在做性能优化,之前有一个业务是这样实现的: 1.温度报警后第三方通讯管理机直接把报警信息保存到数据库 2.我们在数据库中添加触发器,(BEFORE INSERT)根据这条报警信息处理业务 ...

随机推荐

  1. Nacos 服务配置中心

    1.因为项目是微服务分布式项目,每个微服务都需要用到配置中心,所以第一步我们先在common中添加相应的依赖 <dependency> <groupId>com.alibaba ...

  2. CNN可视化技术总结(一)--特征图可视化

    导言: 在CV很多方向所谓改进模型,改进网络,都是在按照人的主观思想在改进,常常在说CNN的本质是提取特征,但并不知道它提取了什么特征,哪些区域对于识别真正起作用,也不知道网络是根据什么得出了分类结果 ...

  3. 使用EFCore连接Oracle数据库时出现的问题

    问题 System.TypeLoadException: Method 'Create' in type 'Oracle.EntityFrameworkCore.Infrastructure.Inte ...

  4. Swagger2配置与使用

    Swagger2配置与使用 Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 We ...

  5. 2、剑指offer-字符串——替换空格

    **题目描述** **请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. ...

  6. LOJ10019生日蛋糕

    Mr.W 要制作一个体积为 N*π 的 M 层生日蛋糕,每层都是一个圆柱体. 设从下往上数第 i 蛋糕是半径为 R_i,高度为 H_i 的圆柱.当 i<M 时,要求 R_i>R_{i+1} ...

  7. HDU1814和平委员会

    题目大意: 有n对的人,编号从1-2*n,m对的人之间互相不喜欢,每对人中必徐选1个人加入和平委员会,求字典序最小的解 -------------------------------- 2-SAT问题 ...

  8. IntelliJ IDEA 20 岁了!20 年前的第 1 版曝光…

    IntelliJ IDEA 最近发布了 20 周年庆典: https://www.jetbrains.com/lp/intellijidea-20-anniversary/ IntelliJ IDEA ...

  9. 通过 JFR 与日志深入探索 JVM - TLAB 原理详解

    全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇 什么是 TLAB? TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配 ...

  10. ElasticSearch 入门简介

    公号:码农充电站pro 主页:https://codeshellme.github.io ElasticSearch 是一款强大的.开源的.分布式的搜索与分析引擎,简称 ES,它提供了实时搜索与聚合分 ...