Spring Session Redis会话过期通知应用停机丢失问题确认及解决方案问询
问题1解答:通知丢失是否为Spring Session Redis默认行为
是,该情况属于Spring Session Redis的默认行为。
Spring Session Redis对会话过期事件的监听完全基于Redis原生的Keyspace Notifications实现,而该通知机制底层依赖Redis的Pub/Sub能力,本身是发后即忘的设计,没有事件持久化、离线消息保留的能力。Spring Session官方默认没有额外实现事件缓存、补发逻辑,所以当应用停机断开和Redis的连接时,期间产生的所有会话过期通知都会直接丢失,和你观测到的现象完全一致。
问题2解答:避免通知丢失的行业通用方案
业内通常会组合使用以下几种方案实现可靠的会话过期通知投递:
- 引入Redis Stream做事件持久化中转
放弃直接监听原生Pub/Sub的过期事件,改为自行实现监听逻辑:当接收到Redis的会话过期Pub/Sub事件后,先将事件写入Redis 5.0以上版本支持的Stream结构中。Stream天然支持消息持久化、消费位点记录、消费组ACK机制,就算消费端应用停机,重启后可以从上次提交的消费位点继续拉取事件处理,不会丢失停机期间的消息。 - 增加启动时主动扫描补偿逻辑
新增独立的会话过期时间索引:创建会话时额外往ZSet结构中写入一条记录,score为会话的过期时间戳,value为会话ID。应用每次启动时,先扫描ZSet中score小于当前时间戳的所有记录,批量处理这些已过期会话的业务逻辑,处理完成后删除对应ZSet记录,补处理停机期间漏掉的过期事件。 - 定时任务兜底校验
配置低频率的定时任务(比如每5-10分钟执行一次),扫描上述ZSet索引中已过期但未处理的会话,补充执行过期逻辑,作为前两种机制的兜底,避免极端场景下的事件遗漏。 - 商用消息队列中转
若公司内部已有RocketMQ、RabbitMQ等支持持久化、重试机制的消息中间件,也可以将监听到的会话过期事件先发送到MQ中,业务过期逻辑从MQ消费,利用MQ本身的可靠投递能力避免消息丢失。
内容的提问来源于stack exchange,提问作者Florian Beaufumé
相关产品推荐
相关产品推荐

