Redis(基础)——学习笔记(安装、数据结构、Spring Session、Java操作Redis、SpringBoot操作Redis)
一、什么是 NoSQL?
NoSQL(Not Only SQL),“不仅仅是 SQL”, 泛指非关系型的数据库。NoSQL 不依赖业务逻辑方式存储,而以简单的 key-value 模式存储
。因此大大的增加了数据库的扩展能力。
NoSQL 的代表
NoSQL 的存储格式可以是列式存储,key-value 存储,文档存储,各自的代表产品如下:
1)键值存储: Redis
2)列式存储: HBase
3)文档型存储: MongoDB
二、Redis 简介
2.1 什么是Redis?应用场景?
Redis 是一个高性能的(key/value)分布式内存数据库
,基于内存运行 并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一, 也被人们称为数据结构服务器。Redis 是一个开源(BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(string), 散列(hash), 列表(list), 集合(set), 有序集合(sorted set)。
Redis 性能极高 – Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。
2.2 Redis 优点/应用场景
优点:
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储 Redis支持数据的备份,即 master-slave模式的数据备份 。
应用场景:
内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务 取最新N个数据的操作,如: 可以将最新的10条评论的ID放在Redis的List集合里面 模拟类似于HttpSession这种需要设定过期时间的功能 发布、 订阅消息系统 定时器、计数器 。查看详细应用场景
2.3 CentOS7安装 Redis
2.3 安装
1) 上传安装包到 Linux;
2) 解压到自己指定的目录;(我这里解压到 /root/javaDevEnv/modules)
3) cd到 /root/javaDevEnv/modules/redis目录,输入make 命令
执行编译命令,接下来控制台会输出各种编译过程中输出的内容。(提示:安装 redis 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,要先安装 gcc-c++(c 语言的环境),命令: yum -y install gcc-c++
。如果已安装,可通过 gcc --version
查看版本。)
4) 安装;(在 redis 所在的目录执行命令)(执行完命令后会在redis的目录中生成一个bin目录,该目录中存放redis相关的重要的可执行文件)
make PREFIX=/root/javaDevEnv/modules/redis install
【提示】
- 这里多了一个关键字
PREFIX=
这个关键字的作用是编译的时候用于指定程序存放的路径
。比如我们现在就是指定了redis必须存放在/root/javaDevEnv/modules/redis目录。假设不添加该关键字Linux会将可执行文件存放在/usr/local/bin目录,库文件会存放在/usr/local/lib目录。配置文件会存放在/usr/local/etc目录。其他的资源文件会存放在usr/local/share目录。这里指定目录主要是为了后期维护方便。
2.3.1 前端启动(了解)
在 bin 目录下执行 redis-server 即可启动服务器,会带 1 个界面。缺点是启动后,不能再进行其它操作。如要做其它操作,必须使用 Ctrl+C,此时 redis-server 结束,客户端就不能连接了。
2.3.2 后端启动(重点)
1) 修改redis.conf 配置文件
2) 执行 bin 下的 redis-server 时,带上 redis.conf 。
【提示】
- 开启服务器:在 redis 目录下可使用
./bin/redis-server redis.conf
来后台开启Redis服务器。- 关闭服务器:在 redis 目录下可使用
./bin/redis-cli shutdown
来关闭Redis服务器。- 查看Redis服务器进程:
ps -aux | grep redis
。- 端口监听查看:
netstat -lanp | grep 6379
。- 查看redis版本:
redis-server --version
或者redis-server -v
。
2.3.3 客户端连接(掌握)
bin 目录下有 redis 的客户端,即 redis-cli(Redis Command Line Interface),它是 Redis 自带的基于命令行的 Redis 客户端。
执行 bin/redis-cli
即可连接(登录)redis 服务器。(quit命令或exit命令可退出终端)
如果希望远程连接其它主机或者其它端口的 Redis 服务器,可以加上相应的参数,使用-h
设置远程主机的 ip,使用-p
设置远程主机的端口号。
redis-cli 连上 redis 服务后,可以在命令行向 Redis 服务器发送命令。比如 PING
命令用来测试客户端与 Redis 服务器的连接是否正常,如果连接正常会收到回复 PONG。
2.3.4 远程访问 Redis 服务器
1) 开放端口 6379;
# 开启6379端口【然后重启防火墙,使放行的端口生效】
firewall-cmd --zone=public --add-port=6379/tcp --permanent
# 重启防火墙
firewall-cmd --reload
【提示】
- 查看开启的端口列表:
firewall-cmd --list-ports
;
2) 修改配置文件 redis.conf ,一、注释掉 bind 127.0.0.1(任何 ip 都能远程连接 redis)。二、找到 protected-mode 这行, 将值 yes 改为 no。
【提示】
- 可以输入“/protected-mode”在文件里搜索,改完后保存并退出。
3) 使用图形化工具连接redis服务器。
首先要启动 redis 服务器。
[root@localhost redis]# ./bin/redis-server redis.conf
【提示】
- 关闭redis服务器:
./bin/redis-cli shutdown
。
2.3.5 设置redis密码
【提示】后期补充。
三、Redis 的数据结构
Redis 中 key 是 String 类型,value 根据存储数据不同,有如下类型:
value 的数据类型 | 说明 |
---|---|
String | 字符串,最简单的 k-v 存储。 |
List | 简单的 list,顺序列表,支持首位或者末尾插入数据。 |
Set | 无序 list,查找速度快,适合交集、并集、差集处理。 |
Sorted Set | 有序的 Set。 |
Hash | hash 格 式 , value 为 field-value , 适合ID-Detail 这样的场景。 |
命令 | 说明 |
---|---|
keys * | 查找所有的key。(包括string,hash,list,set,zset) |
del key[key ...] | 删除指定key。 |
`` | |
`` | 更多命令可查看:www.redis.cn |
3.1 String
String 是 redis 最基本的类型,一个 key 对应一个 value。String 类型是二进制安全的。意思是 redis 的 String 可以包含任何数据。比如jpg图片或者序列化的对象。
String 类型是 Redis 最基本的数据类型,String 类型的值最大能存储 512MB。
命令 | 说明 |
---|---|
set key value | 设定 key 持有指定的字符串 value,如果该 key 存在则进行覆盖操作。总是返回”OK”。 如果value中含有空格的话可以使用单引号 '' 将整个value括起来。 |
get key | 获取 key 的 value。 如果与该 key 关联的 value 不是 String 类型,redis将返回错误信息。 如果该 key 不存在,返回 null。 |
incr key | 将指定的 key 的 value 原子性的递增 1。 如果该 key 不存在,其初始值为 0,在 incr 之后其值为 1。 如果 value 的值不能转成整型,如 hello,该操作将执行失败并返回相应的错误信息。 |
decr key | 将指定的 key 的 value 原子性的递减 1。 如果该 key 不存在,其初始值为 0,在 decr 之后其值为-1。 如果 value 的值不能转成整型,如 hello,该操作将执行失败并返回相应的错误信息。 |
append key value | 如果该 key 存在,则在原有的 value 后追加该值; 如果该key不存在,则重新创建一个 key/value。 |
3.2 List
Redis 的列表相当于 Java 语言里面的 LinkedList,是链表而不是数组 。这意味着list 的插入和删除操作非常快,时间复杂度为 O(1),但是查找数据很慢,时间复杂度为 O(n) 。
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。在插入时,如果该键并不存在,Redis 将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除 ,那么该键也将会被从数据库中删除。 List 中可以包含的最大元素数量是 4294967295。
命令 | 说明 |
---|---|
lpush key value1 value2 ... | 在指定的 key 所关联的 list 的头部插入所有的values。 如果该 key 不存在,该命令在插入的之前创建一个与该 key 关联的空链表,之后再向该链表的头部插入数据。 插入成功,返回元素的个数。 |
rpush key value1、value2 ... | 在该 list 的尾部添加元素。 如果该key不存在则创建该key的链表,再插入数据。 |
lrange key start end | 获取链表中从 start 到 end 的元素的值。(下标从0开始) start、end 可为负数,若为-1 则表示链表尾部的元素,-2 则表示倒数第二个,依次类推… |
lpop key | 返回并弹出(即删除)指定的 key 关联的链表中的第一个元素,即头部元素。 |
rpop key | 从尾部弹出(即删除)元素。 |
llen key | 返回指定的key关联的链表中的元素的数量。 |
lset key index value | 设置链表中的 index 的脚标的元素值,0 代表链表的头元素,-1 代表链表的尾元素。 |
3.3 Set
Redis 的 Set 是 string 类型的无序集合(集合中不允许有重复的元素)。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
和 List 类型相比,Set 类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个 Sets 之间的聚合计算操作,如 unions、intersections 和 differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络 IO 开销。
命令 | 说明 |
---|---|
sadd key value、value2 ... | 向 set 中添加数据,如果该 key 的值已有则不会重复添加 。 |
smembers key | 获取 set 中所有的成员。 |
scard key | 获取 set 中成员的数量。 |
sismember key value | 判断参数中指定的成员(value)是否在该 set 中,1 表示存在,0 表示不存在或者该 key 本身就不存在。 |
srem key member1 member2 ... | 删除 set 中指定的成员。 |
srandmember key | 随机返回 set 中的一个成员。 |
sdiff key1 key2 | 返回 key1 与 key2 中相差的成员,而且与 key 的顺序有关。即返回差集。 即返回key1绑定的集合中key2绑定集合中没有的元素。 |
sdiffstore destination key1 key2 | 将 在key1中而不在key2中的元素存储在destination 上。 |
sinter key1 key2 ... | 返回交集。 |
sinterstore destination key1 key2 ... | 将返回的交集存储在 destination 上。(如果destination中有值的话将会被覆盖!) |
sunion key1 key2 ... | 返回并集。 |
sunionstore destination key1 key2 ... | 将返回的并集存储在 destination 上。 |
3.4 ZSet
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
命令 | 说明 |
---|---|
zadd key score member score2 member2 ... | 将所有成员以及该成员的分数存放到 sorted-set 中 。 |
zcard key | 获取集合中的成员数量。 |
zcount key min max | 获取分数在[min,max]之间的成员数量。 |
zincrby key increment member | 设置指定成员的增加的分数。返回增加后的分数。 详情:如果该成员在集合中存在,则分数增加给定的增量值。当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。 例句:myzset中的成员 lisi 的分数增加2 zincrby myzset 2 "lisi" |
zrange key start end[withscores] | 获取集合中脚标为 start-end 的成员,[withscores]参数表明返回的成员包含其分数。end=-1:表示最后一个成员。 例句:获取key=ccbx,中从第一个成员到第2个成员的值并且同时输出分数: zrange ccbx 0 2 withscores |
zrangebyscore key min max [withscores] [limit offset count] | 返回分数在[min,max]的成员并按照分数从从低到高排序。 [withscores] :显示分数; [limit offset count]:offset,表示从下表为offset的元素开始并返回count个成员。 |
zrank key member | 返回成员在集合中的位置。(从0开始) |
zrem key member ... | 移出集合中指定的成员,可以指定多个成员。 |
zscore key member | 返回指定成员的分数。 |
3.5 Hash
Redis hash 是一个键值(key=>value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。每一个Hash 可以存储 4294967295 个键值对。
命令 | 说明 |
---|---|
hset key field value | 为指定的key设定 field/value 对(键值对)。 多个属性也可以多次添加。(不太推荐) |
hgetall key | 获取key中所有的 field-vlaue 。 |
hget key field | 返回指定的 key 中的 field 的值。 |
hmset key field1 value1 field2 value2 ... | 设置 key 中的多个 filed/value 。 |
hmget key fileld1 field2 ... | 获取 key 中的多个 filed 的值。 |
hexists key field | 判断指定的 key 对应 hash 中的 filed 是否存在。(返回1:存在。返回0:不存在) |
hdel key field[field ...] | 删除指定 key 中一个或多个 field。(返回删除的数量) |
hlen key | 获取 key 所包含的 field 的数量。 |
hincrby key field increment | 设置 key 中 filed 的值增加 increment(注意数据类型)。如:age增加 20。 |
四、Java 操作Redis
【备注】此部分后期补充。
五、Spring Boot 使用Redis
5.1 引入依赖
<!-- redis的启动依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 【可选】添加对象池化的框架(连接池工具),优化连接性能 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>
5.2 application.yml配置redis
# Redis 相关配置
spring:
redis:
host: 192.168.238.66 # Redis 服务器主机。
port: 6379 # Redis 服务器端口。(默认:6379)
database: 1 # 连接工厂使用的数据库索引。(默认:0)
timeout: 30000 # 读取超时。(单位:毫秒)
#可扩展的线程安全Redis客户端,用于同步、异步和反应式使用
lettuce:
pool: #Redis的池属性
max-active: 20 #连接池的最大连接数,负数表示没有限制。
max-wait: -1 #最大阻塞等待时间 (负数表示没限制)
max-idle: 6 #最大空闲连接数量(负数表示没有限制)
min-idle: 0 #最小连接数
5.3 自定义 Redis 配置类
package com.ccbx.config;
/**
* @Description 自定义的Redis配置类
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
// 在给定对象和 Redis 存储中的底层二进制数据之间执行自动序列化/反序列化。
// 如果使用自动配置类中的RedisTemplate对象,该对象默认对key和value都采用JDK序列化器来序列化
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 构造一个新的RedisTemplate实例。(如果只是操作字符串,还可以用 StringRedisTemplate)
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂。
template.setConnectionFactory(factory);
// 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
/**
* ObjectMapper 提供了读取和写入 JSON 的功能,
* 可以与基本 POJO(Plain Old Java Objects)
* 或通用 JSON 树模型 ( JsonNode ) 之间进行读取和写入,以及用于执行转换的相关功能。
*/
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//简单String到字节 [](和返回)序列化程序。
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
//Spring 的中央缓存管理器 SPI。
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间 600 秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.
fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();
return cacheManager;
}
}
5.4 调用 RedisTemplate 的 API
首先注入上面的自定义的Bean。
@Autowired
private RedisTemplate redisTemplate;
然后调用 redisTemplate 对象的相关命令,如下:
命令 | 说明 |
---|---|
redisTemplate.boundValueOps(key) | 操作 string |
redisTemplate.boundListOps(key) | 操作 list |
redisTemplate.boundSetOps(key) | 操作 set |
redisTemplate.boundZSetOps(key) | 操作 ZSet |
redisTemplate.boundHashOps(key) | 操作 Hash |
【备注】如果只是操作字符串,还可以用 StringRedisTemplate。
StringRedisTemplate 和 RedisTemplate 区别:
- StringRedisTemplate 继承 RedisTemplate。
- StringRedisTemplate 默认采用的是 String 的序列化策略(StringRedisSerializer),保存的key和 value 都是采用此策略序列化保存的。
- RedisTemplate 默认采用的是 JDK 的序列化策略(JdkSerializationRedisSerializer),保存的key 和 value 都是采用此策略序列化保存的。
六、Spring session(session共享)
使用Spring Session+Redis实现session共享。
Session共享
就是在分布式系统中,解决session不一致问题。当我们的应用需要两个或者两个以上的tomcat服务器来支撑时,就要考虑Session共享了。Session共享也叫Session同步或者Session一致性。
Spring为我们提供了Spring Session进行管理我们的HttpSession。Spring session 是将HttpSession存放在Redis中,这样我们session就能在多个服务器共享了。Session共享的步骤如下:
6.1 引入依赖
<!-- redis的启动依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 添加连接池优化封装工具 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.9.0</version>
</dependency>
<!-- Spring Session依赖 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
6.2 application.yml配置spring session
spring:
session:
store-type: redis #会话的存储类型( Redis 支持的会话)
# Redis 相关配置(参考上面redis的配置)
6.3 @EnableRedisHttpSession注解
@EnableRedisHttpSession注解:这个注解的主要作用是注册一个 SessionRepositoryFilter
,这个 Filter 会拦截所有的请求,对 Session 进行操作,也就是开启 Session 共享功能。详细源码解析参考
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 24*60*60)
public class RedisSessionConfig {
/**
* maxInactiveIntervalInSeconds: 设置 Session 失效时间。(单位:秒)
* 使用 Redis Session 之后,原 Spring Boot的 server.session.timeout属性不再生效。
* 经过上面的配置后,Session 调用就会自动去Redis存取。
* 另外,想要达到 Session 共享的目的,只需要在其他的系统上做同样的配置即可。
*/
}
属性 | 说明 |
---|---|
maxInactiveIntervalInSeconds | 设置 Session 失效时间。(单位:秒) |
redisFlushMode | Redis 会话的刷新模式。(默认值为 ON_SAVE ) |
cleanupCron | 过期会话清理作业的 cron 表达式。 默认情况下每分钟运行一次。 |
redisNamespace | 为键定义唯一的命名空间。 提示:该值用于通过将前缀从默认spring:session:更改为< redisNamespace>:来隔离会话。 |
saveMode | 会话的保存模式。 |
6.4 测试的类
编写测试类:
@Controller
public class RedisSessionTestController {
//跳转到登录页面
@RequestMapping("/")
public String tologin(HttpSession session,HttpServletRequest req, Model model){
System.out.println("sessionID:"+session.getId()+"服务器端口号:"+req.getServerPort());
return "login";
}
//列表页面
@RequestMapping("tologin")
public String productlist(HttpSession session, HttpServletRequest req){
session.setAttribute("loginUser",new User("张良",22));
System.out.println("sessionID:"+session.getId()+"服务器端口号:"+req.getServerPort());
return "list";
}
}
使用图形界面查看redis中存入的相关信息:
redis存储的session相关结构信息:
spring:session:expirations:
(Set 结构):用户 ttl 过期时间记录 , 这个 key中的值是一个时间戳,根据这个 Session 过期时刻滚动至下一分钟而计算得出。这个 key 的过期时间为 Session 的最大过期时间 +5 分钟。spring:session:sessions:
(Hash 结构):sessionAttr:Attribute名, 存储 Session 的详细信息,包括 Session 的过期时间间隔、最后的访问时间、attributes 的值。这个 key 的过期时间为 Session 的最大过期时间 +5 分钟。spring:session:sessions:expires:
(String 结构):过期时间记录 : 这个 k-v 不存储任何有用数据,只是表示 Session 过期而设置。这个 key 在 Redis 中的过期时间即为 Session 的过期时间间隔。
6.5 更改 Spring Session的序列化器
Spring Session 中默认的序列化器为(JdkSerializationRedisSerializer
),该序列化器效率低下,内存占用大。我们可以根据自己的需要更换其他序列化器,如 GenericJackson2JsonRedisSerializer
序列化器。部分源码解析如下:(从@EnableRedisHttpSession注解开始查看)
RedisHttpSessionConfiguration.class(部分代码)
@Configuration(proxyBeanMethods = false)
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware {
//容器中查找注入默认的redis序列化器
@Autowired(required = false)
@Qualifier("springSessionDefaultRedisSerializer")
public void setDefaultRedisSerializer(RedisSerializer<Object> defaultRedisSerializer) {
this.defaultRedisSerializer = defaultRedisSerializer;
}
//session持久化
@Bean
public RedisIndexedSessionRepository sessionRepository() {
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate();
RedisIndexedSessionRepository sessionRepository = new RedisIndexedSessionRepository(redisTemplate);
if (this.indexResolver != null) {
sessionRepository.setIndexResolver(this.indexResolver);
}
if (this.defaultRedisSerializer != null) {
//设置session的持久化时,设置默认的序列化器
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
}
//省略部分代码
return sessionRepository;
}
}
RedisIndexedSessionRepository.class(部分代码)
public class RedisIndexedSessionRepository
implements FindByIndexNameSessionRepository<RedisIndexedSessionRepository.RedisSession>, MessageListener {
private RedisSerializer<Object> defaultSerializer = new JdkSerializationRedisSerializer();
/**
* 设置默认的 redis 序列化程序。
* 替换基于JdkSerializationRedisSerializer默认序列化JdkSerializationRedisSerializer 。
*/
public void setDefaultSerializer(RedisSerializer<Object> defaultSerializer) {
Assert.notNull(defaultSerializer, "defaultSerializer cannot be null");
this.defaultSerializer = defaultSerializer;
}
}
在配置类中创建自定义序列化器:
@Configuration
public class SpringSessionConfig {
/**
* 更换序列化器(spring session默认使用的是jdk的序列化器)
* @return
*/
@Bean("springSessionDefaultRedisSerializer")
public RedisSerializer setSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
再次运行项目查看序列化效果:
【注意】要序列化的类
必须实现 java.io.Serializable 接口
(很重要!!)。未实现此接口的类将不会对其任何状态进行序列化或反序列化。
5.5 Nginx负载均衡查看session共享
1) 将完成的项目打成 jar 包,传到服务器的目录中:/root/jars 。
2) 启动Nginx服务器;(配置如下)
# nginx负载均衡实验(不要忘记重新加载nginx服务器,使该配置生效)
upstream myTomcatServer{
# 默认使用 轮询的方式进行访问映射的tomcat服务器
server 192.168.238.66:8080;
server 192.168.238.66:8081;
#server 192.168.238.66:8082;
}
server{
listen 9005; # 设置好端口号后要通知防火墙开放该端口号,并重启防火墙
server_name www.123.com;
location / {
proxy_pass http://myTomcatServer;
}
}
3) 使用命令行运行 jar 包项目。
# 使用项目中默认的端口运行内嵌的tomcat (8080)
java -jar /root/jars/redis-session.jar
# 使用指定的端口号运行内嵌的tomcat(8081)
java -jar jars/redis-session.jar --server.port=8081
4) 查看session共享情况。
【拓展知识】Spring Session提供了3种方式存储session的方式:
@EnableRedisHttpSession
-存放在缓存redis@EnableMongoHttpSession
-存放在Nosql的MongoDB@EnableJdbcHttpSession
-存放在数据库