便宜有便宜的办法-小微企业云上的springboot集群方案2.1:redis的消息订阅和session过时机制

一、session在redis里面的存储结构2

上一章讲spring session存储到redis的时候,在redis里面看到每个session存储都会生成三条记录,记录格式以下:html

这就很麻烦了,为啥不能一一对应,作彼此的天使呢,搞的一对三,很影响风化啊。究竟是道德的沦丧仍是人性的扭曲,让咱们走进redis,看下具体的数据内容:java

第一个k-v存储这个Session的id,是一个Set类型的Redis数据结构。这个key中的最后的1570550340000值是一个时间戳,根据这个Session过时时刻滚动至下一分钟而计算得出。里面的值是这样的redis

第二个k-v用来表示Session在Redis中的过时,是个String类型,这个k-v不存储任何有用数据,只是表示Session过时而设置。这个key在Redis中的过时时间即为Session的过时时间间隔spring

第三个k-v用来存储Session的详细信息,是hash类型,包括Session的建立时间、过时时间间隔、最近的访问时间、attributes等等。这个k的过时时间为Session的最大过时时间 + 5分钟。若是默认的最大过时时间为30分钟,则这个k的过时时间为35分钟数据库

说到这里,会有个灵魂的拷问,就一个session的存储,为啥要搞三条记录?这里要提一下HttpSession的接口规范了。缓存

session虽然也是一条数据,可是和普通的数据仍是有不一样的,咱们去查httpsession的javadoc能够看到,session的添加和移除都是能够触发事件的。bash

触发的前提是对象实现了HttpSessionBindingListener接口,而后咱们再看下HttpSessionBindingListener的部分session

里面经过HttpSessionBindingEvent来通知session的attribute变化数据结构

这一套下来是否是很熟悉,这就是一个典型的监听器模型,也是消息机制的主要表现方式,在spring session经过redis实现分布式的session时,就是经过redis的消息机制来实现标准的session变更通知的,在了解具体的作法先,让咱们先看下redis的消息通知功能。app

二、啥!redis支持消息的发布订阅?

Redis从2.8.0版本后,推出 Keyspace Notifications 特性。Keyspace Notifications 容许客户端能够以 订阅/发布(Sub/Pub)模式,接收那些对数据库中的键和值有影响的操做事件。这些操做事件具体来讲,就是 del , expire , set , rpop等啦。

redis默认不会开启keyspace notifications,由于开启后会对cpu有消耗,因此开启须要额外配置redis.conf文件

############################# EVENT NOTIFICATION ##############################

# Redis can notify Pub/Sub clients about events happening in the key space.
# This feature is documented at http://redis.io/topics/notifications
#
# For instance if keyspace events notification is enabled, and a client
# performs a DEL operation on key "foo" stored in the Database 0, two
# messages will be published via Pub/Sub:
#
# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo
#
# It is possible to select the events that Redis will notify among a set
# of classes. Every class is identified by a single character:
#
# K Keyspace events, published with __keyspace@<db>__ prefix.
# E Keyevent events, published with __keyevent@<db>__ prefix.
# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
# $ String commands
# l List commands
# s Set commands
# h Hash commands
# z Sorted set commands
# x Expired events (events generated every time a key expires)
# e Evicted events (events generated when a key is evicted for maxmemory)
# A Alias for g$lshzxe, so that the "AKE" string means all the events.
#
# The "notify-keyspace-events" takes as argument a string that is composed
# of zero or multiple characters. The empty string means that notifications
# are disabled.
#
# Example: to enable list and generic events, from the point of view of the
# event name, use:
#
# notify-keyspace-events Elg
#
# Example 2: to get the stream of the expired keys subscribing to channel
# name __keyevent@0__:expired use:
#
# notify-keyspace-events Ex
#
# By default all notifications are disabled because most users don't need
# this feature and the feature has some overhead. Note that if you don't
# specify at least one of K or E, no events will be delivered.
notify-keyspace-events "Ex"复制代码

关键就是最下一句,Ex的意思能够看上面的注释。启动后只要咱们订阅一个特定的channel,该channel下面的数据变化咱们就能收到通知了。

改好配置,重启redis,就可以开启消息通知了。

Redis中带有过时的key有两种方式:

  • 当访问时发现其过时
  • Redis后台逐步查找过时键

问题时访问时发现过时可能会在好久之后,因此怎么才能在key过时的时候就知道呢?

spring-session中有个定时任务,每一个整分钟都会查询相应的spring:session:expirations:整分钟的时间戳中的过时SessionId,而后再访问一次这个sessionId,即spring:session:sessions:expires:SessionId,以便可以让Redis及时的产生key过时事件——即Session过时事件。而这个定时任务的时间时能够配置的,配置的参数就时上一章结尾说的cleanupCron

public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
		implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware,
		SchedulingConfigurer {

	static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";

	private String cleanupCron = DEFAULT_CLEANUP_CRON;复制代码

默认就是一分钟清理一次过时的缓存,能够根据本身的需求作更改。

三、总结

  1. spring session存到redis的每一个session数据会有三条记录,一条存储session自身的信息,另外两条存储session过时的信息
  2. redis能够开启Keyspace Notifications服务,开启后redis的数据出现变更会有通知消息
  3. spring session能够配置定时任务扫描存到redis的session数据中关于过时信息的两条,定时任务的配置在cleanupCron里面

我这里其实讲的不是很详细,关于spring session方面的细节,你们能够看这一系列的文章,讲的很好,但看的挺累。

相关文章
相关标签/搜索