• Spring+Redis(keyspace notification)实现定时任务(订单过期自动关闭)


    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的值,这样就可以做自定义的操作了。

    3.后记

    欢迎大家留言交流,关于订单自动关闭如果有更好的方式,还望不吝赐教,O(∩_∩)O谢谢。

    Keyspace Notifications

    作者: 采采灬卷耳

    <http://www.cnblogs.com/floay/>

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 欢迎咨询。

  • 相关阅读:
    WCF服务编程 读书笔记——第1章 WCF基础(2)
    WCF服务编程 读书笔记——第1章 WCF基础(1)
    设计模式17:Iterator 迭代器模式(行为型模式)
    设计模式16:Mediator 中介者模式(行为型模式)
    设计模式23:Visitor 访问者模式(行为型模式)
    设计模式22:Strategy 策略模式(行为型模式)
    设计模式21:State 状态模式(行为型模式)
    Python常用库之二:Pandas
    Python常用库之一:Numpy
    TensorFlow基础(三)激活函数
  • 原文地址:https://www.cnblogs.com/floay/p/6708186.html
Copyright © 2020-2023  润新知