文章目录
场景描述修改redis.conf配置,以拿到发布的key继承事件监听器,重写onMessage方法编写配置类,注入Bean测试结果存在缺陷
场景描述
电商平台,客户下单未支付,会有锁库存的操作,支付有效时间为15min,15分钟之后订单失效,释放库存,修改订单状态。如何实现?
默认已连接redis,并在springboot引入依赖
修改redis.conf配置,以拿到发布的key
继承事件监听器,重写onMessage方法
public class KeyExpiredListener extends KeyExpirationEventMessageListener {
private static final Logger LOGGER
= LoggerFactory
.getLogger(KeyExpiredListener
.class);
public KeyExpiredListener(RedisMessageListenerContainer listenerContainer
) {
super(listenerContainer
);
}
@Override
public void onMessage(Message message
, byte[] pattern
) {
String channel
= new String(message
.getChannel(),StandardCharsets
.UTF_8
);
String key
= new String(message
.getBody(),StandardCharsets
.UTF_8
);
String patternStr
= new String(message
.getBody(),StandardCharsets
.UTF_8
);
LOGGER
.info("key失效:channel:{},key:{},patternStr:{}",channel
,key
,patternStr
);
if (!StringUtils
.isEmpty(key
) && key
.startsWith("orderId:")){
String
[] split
= key
.split(":");
Long orderId
= Long
.parseLong(split
[1]);
}
}
}
编写配置类,注入Bean
@Configuration
public class RedisConfiguraion {
@Autowired
private RedisConnectionFactory redisConnectionFactory
;
@Bean
public RedisMessageListenerContainer
redisMessageListenerContainer(){
RedisMessageListenerContainer redisMessageListenerContainer
= new RedisMessageListenerContainer();
redisMessageListenerContainer
.setConnectionFactory(redisConnectionFactory
);
return redisMessageListenerContainer
;
}
@Bean
public KeyExpiredListener
keyExpiredListener(){
return new KeyExpiredListener(redisMessageListenerContainer());
}
@Bean
public PatternTopic
patternTopic(){
return new PatternTopic("__keyevent@0__:expired");
}
}
测试结果
存在缺陷
redis的pus/sub不管有没有收到信息,都只发一次!存在网络抖动,发生异常等,意味着可能存在监听丢失,逾期订单不取消。redis-key单线程,同一时间大量失效,可能存在延迟。如果orderservice服务是集群配置,所有客户端都会收到key失效的event;此时加上redis分布式锁处理。