基於Redis過期事件實現訂單超時取消
阿新 • • 發佈:2021-10-18
訂單超時取消的實現,首先想到的是定時任務,但是這種實現方式在訂單量較大的情況下是有問題的,而且時間也會有誤差,最大時間差就是定時任務的執行間隔時間。
使用redis的過期監聽事件可以比較好的解決這個問題。實現的方式是訂單建立後向redus中存一記錄,一般就以訂單號為key。設定過期時間(訂單超時時間),一旦時間超時會觸發監聽事件,這時候就可以通過key判斷這個訂單是否支付,未支付時取消訂單。
redis過期監聽的實現:
1.修改redis.windows.conf配置檔案中notify-keyspace-events的值
預設配置notify-keyspace-events的值為" ",修改為notify-keyspace-events Ex 這樣便開啟了過期事件
2.建立配置類RedisListenerConfig(配置RedisMessageListenerContainer這個Bean)
@Configuration public class RedisListenerConfig { @Autowired private RedisTemplate redisTemplate; /** * 處理亂碼 * @return */ @Bean public RedisTemplate redisTemplateInit() { // key序列化 redisTemplate.setKeySerializer(newStringRedisSerializer()); //val例項化 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container= new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
3.繼承KeyExpirationEventMessageListener建立redis過期事件的監聽類
KeyExpirationEventMessageListener類是org.springframework.data.redis.listener包下的實現類,通過繼承這個類重寫onMessage方法可以實現對redis所有過期事件的監聽。
@Component public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { public RedisKeyExpirationListener(RedisMessageListenerContainer container) { super(container); } /** * 針對redis資料失效事件,進行資料處理 * @param message * @param pattern */ @Override public void onMessage(Message message, byte[] pattern) { String key=message.toString();//生效的key if (key!=null && key.startsWith("order")){//從失效key中篩選代表訂單失效的key //擷取訂單號,查詢訂單,如果是未支付狀態則取消訂單 String orderNo=key.substring(5); System.out.println("訂單號為:"+orderNo+"的訂單超時未支付,取消訂單"); } } }
測試
通過redis模擬建立一個有效時間為5s的訂單:
5秒後程序成功監聽到了過期事件: