您的位置:首页 > 数据库 > Redis

spring中订阅redis键值过期消息通知

2017-08-10 10:44 337 查看

1.起因

最近公司项目要做订单超期未支付需自动关闭,首先想到的是用spring的定时器(@Schedule),结果领导举各种例子说会影响性能,只能作罢。后来想能不能基于redis实现,学习(baidu)之后,大概就是使用redis的Keyspace
Notifications,大概就是利用该机制可以在key失效之后,提供一个回调,实际上是redis会给客户端发送一个消息。是需要redis版本2.8以上,conf配置需设置notify-keyspace-events Ex,请示领导之后也得到了同意。

2.整合实现

大致思路就是让spring做客户端订阅'__keyevent@0__:expired'频道就可以了。在这里给出两种实现方式。
1.利用MessageListenerAdapter,spring本身已经提供了的实现方式。
首先自定义一个MessageDelegate
接口并实现

1 public interface MyMessageDelegate {
2   void handleMessage(String message);
3   void handleMessage(Map message); void handleMessage(byte[] message);
4   void handleMessage(Serializable message);
5   // pass the channel/pattern as well
6   void handleMessage(Serializable message, String channel);
7  }
8
9 public class MyRedisKeyExpiredMessageDelegate implements MessageDelegate {
10   // implementation elided for clarity...
11 }


xml增加相关配置

<bean id="messageListener"
class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg>
<bean class="com.xxx.MyRedisKeyExpiredMessageDelegate" />
</constructor-arg>
</bean>
<bean id="redisContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="messageListeners">
<map>
<entry key-ref="messageListener">
<list>
<bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="__keyevent@0__:expired" />
</bean>
</list>
</entry>
</map>
</property>
</bean>


具体可参考官方文档:http://docs.spring.io/spring-data/redis/docs/1.7.8.RELEASE/reference/html/#redis:pubsub:subscribe
2.即自定义一个OrderPubSub类继承自JedisPubSub,然后在spring启动的时候就订阅这个OrderPubSub。

1 public class OrderSubscribe extends JedisPubSub {
2
3     public void onPSubscribe(String pattern, int subscribedChannels) {
4
5     }
6
7     public void onPMessage(String pattern, String channel, String message) {
8             if ("__keyevent@0__:expired".equals(channel)) {
9                 //do some thing
10             }
11     }
12 }
13
14 public class RedisInitSubscrib implements InitializingBean{
15
16     JedisPool pool;
17
18     @Override
19     public void afterPropertiesSet() throws Exception {
20         pool.getResource().psubscribe(new OrderSubscribe(), "*");
21
22     }
23
24 }


当key失效后,收到消息的内容(即方法中的message参数)就是key的值,这样就可以做自定义的操作了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java spring redis