前言
用戶下單后,規定XX分鐘后自動設置為“已過期”,不能再發起支付。項目類似此類"過期"的需求,筆者提供一種使用Redis的解決思路,結合Redis的訂閱、發布和鍵空間通知機制(Keyspace Notifications)進行實現。
配置redis.confg
notify-keyspace-events選項默認是不啟用,改為notify-keyspace-events “Ex”。重啟生效,索引位i的庫,每當有過期的元素被刪除時,向**keyspace@:expired**頻道發送通知。
E表示鍵事件通知,所有通知以__keyevent@__:expired為前綴;
x表示過期事件,每當有過期被刪除時發送。
與SpringBoot進行集成
①注冊JedisConnectionFactory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; @Configuration public class RedisConfig { @Value ( "${redis.pool.maxTotal}" ) private Integer maxTotal; @Value ( "${redis.pool.minIdle}" ) private Integer minIdle; @Value ( "${redis.pool.maxIdle}" ) private Integer maxIdle; @Value ( "${redis.pool.maxWaitMillis}" ) private Integer maxWaitMillis; @Value ( "${redis.url}" ) private String redisUrl; @Value ( "${redis.port}" ) private Integer redisPort; @Value ( "${redis.timeout}" ) private Integer redisTimeout; @Value ( "${redis.password}" ) private String redisPassword; @Value ( "${redis.db.payment}" ) private Integer paymentDataBase; private JedisPoolConfig jedisPoolConfig() { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(maxTotal); config.setMinIdle(minIdle); config.setMaxIdle(maxIdle); config.setMaxWaitMillis(maxWaitMillis); return config; } @Bean public JedisPool jedisPool() { JedisPoolConfig config = this .jedisPoolConfig(); JedisPool jedisPool = new JedisPool(config, redisUrl, redisPort, redisTimeout, redisPassword); return jedisPool; } @Bean (name = "jedisConnectionFactory" ) public JedisConnectionFactory jedisConnectionFactory() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setDatabase(paymentDataBase); redisStandaloneConfiguration.setHostName(redisUrl); redisStandaloneConfiguration.setPassword(RedisPassword.of(redisPassword)); redisStandaloneConfiguration.setPort(redisPort); return new JedisConnectionFactory(redisStandaloneConfiguration); } } |
②注冊監聽器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service (value = "paymentListener" ) public class PaymentListener implements MessageListener { @Override @Transactional public void onMessage(Message message, byte [] pattern) { // 過期事件處理流程 } } |
③配置訂閱對象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; @Configuration @AutoConfigureAfter (value = RedisConfig. class ) public class PaymentListenerConfig { @Autowired @Qualifier (value = "paymentListener" ) private PaymentListener paymentListener; @Autowired @Qualifier (value = "paymentListener" ) private JedisConnectionFactory connectionFactory; @Value ( "${redis.db.payment}" ) private Integer paymentDataBase; @Bean RedisMessageListenerContainer redisMessageListenerContainer(MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); // 監聽paymentDataBase 庫的過期事件 String subscribeChannel = "__keyevent@" + paymentDataBase + "__:expired" ; container.addMessageListener(listenerAdapter, new PatternTopic(subscribeChannel)); return container; } @Bean MessageListenerAdapter listenerAdapter() { return new MessageListenerAdapter(paymentListener); } } |
paymentDataBase 庫元素過期后就會跳入PaymentListener 的onMessage(Message message, byte[] pattern)方法。
到此這篇關于Redis實現訂單自動過期功能的示例代碼的文章就介紹到這了,更多相關Redis 訂單自動過期內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_33755556/article/details/87457332