springboot使用redis的keyspace notifications

来源:互联网 发布:德州大气环境监测数据 编辑:程序博客网 时间:2024/05/16 09:19
简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件)需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本以上;(A)业务场景:1、当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务2、redis的keyspace notifications 会在key失效后发送一个事件,监听此事件的的客户端就可以收到通知(B)服务准备:    1、修改reids配置文件(redis.conf)        redis默认不会开启keyspace notifications,因为开启后会对cpu有消耗        备注:            E:keyevent事件,事件以__keyevent@<db>__为前缀进行发布;            x:过期事件,当某个键过期并删除时会产生该事件;        配置如下:            notify-keyspace-events "Ex"    2、重启redis就可以了,我们测试一下我们有没有修改成功。    开启一个客户端用来监听:        [test@127.0.0.1 ~]$ redis-cli        127.0.0.1:6379> psubscribe __keyevent@0__:expired        Reading messages... (press Ctrl-C to quit)        1) "psubscribe"        2) "__keyevent@0__:expired"        3) (integer) 1    开启一个发送key的客户端:        [test@127.0.0.1 ~]$ redis-cli        127.0.0.1:6379> set testKey 123 PX 100        OK        127.0.0.1:6379>    结果:        [test@127.0.0.1 ~]$ redis-cli        127.0.0.1:6379> psubscribe __keyevent@0__:expired        Reading messages... (press Ctrl-C to quit)        1) "psubscribe"        2) "__keyevent@0__:expired"        3) (integer) 1        1) "pmessage"        2) "__keyevent@0__:expired"        3) "__keyevent@0__:expired"        4) "testKey"    这样代表测试成功!(C)springBoot工程引用    1、配置文件 application.properties加入如下配置
spring.redis.host=127.0.0.1spring.redis.pool.max-active=8spring.redis.pool.max-idle=8spring.redis.pool.max-wait=-1spring.redis.pool.min-idle=0spring.redis.timeout=3000spring.redis.password=123456spring.redis.port=6379
    2、在com.xxx.xxx下添加RedisConfiguration类 
package com.xxx.xxx;        import org.slf4j.Logger;        import org.slf4j.LoggerFactory;        import org.springframework.beans.factory.annotation.Value;        import org.springframework.cache.annotation.CachingConfigurerSupport;        import org.springframework.context.annotation.Bean;        import org.springframework.stereotype.Component;        import redis.clients.jedis.JedisPool;        import redis.clients.jedis.JedisPoolConfig;        /**         * Created by test on 2017/2/12.         */        @Component        public class RedisConfiguration extends CachingConfigurerSupport {            Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);            @Value("${spring.redis.host}")            private String host;            @Value("${spring.redis.port}")            private int port;            @Value("${spring.redis.timeout}")            private int timeout;            @Value("${spring.redis.pool.max-idle}")            private int maxIdle;            @Value("${spring.redis.pool.max-wait}")            private long maxWaitMillis;            @Value("${spring.redis.password}")            private String password;            @Bean            public JedisPool redisPoolFactory() {                logger.info("JedisPool注入成功!!");                logger.info("redis地址:" + host + ":" + port);                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();                jedisPoolConfig.setMaxIdle(maxIdle);                jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);                JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout,password);                return jedisPool;            }        }    3、在com.xxx.xxx下创建redisKeyspace包    并创建一个Subscribe.java类        package com.xxx.xxx.redisKeyspace;        import org.apache.commons.logging.Log;        import org.apache.commons.logging.LogFactory;        import redis.clients.jedis.JedisPubSub;        /**         * Created by test on 2017/2/12.         */        public class Subscribe extends JedisPubSub {            private static final Log log= LogFactory.getLog(Subscribe.class);            // 初始化按表达式的方式订阅时候的处理            public void onPSubscribe(String pattern, int subscribedChannels) {                log.info("Subscribe-onPSubscribe>>>>>>>>>>>>>>>>>>>>>>>>"+pattern + "=" + subscribedChannels);            }            // 取得按表达式的方式订阅的消息后的处理            public void onPMessage(String pattern, String channel, String message) {                try {                    log.info(pattern + "=" + channel + "=" + message);                    //在这里写你相关的逻辑代码                }catch (Exception e){                    e.printStackTrace();                }            }        }
3、创建SubscribeThread.java线程类    备注:此线程实现了CommandLineRunner,springBoot的CommandLineRunner 可以达到工程已启动就开启一个线程        
package com.xxx.xxx.redisKeyspace;        import org.apache.commons.logging.Log;        import org.apache.commons.logging.LogFactory;        import org.springframework.beans.factory.annotation.Autowired;        import org.springframework.boot.CommandLineRunner;        import org.springframework.stereotype.Component;        import redis.clients.jedis.Jedis;        import redis.clients.jedis.JedisPool;        /**         * Created by test on 2017/2/13.         */        @Component        public class SubscribeThread implements CommandLineRunner {            private Log log= LogFactory.getLog(SubscribeThread.class);            @Autowired            JedisPool jedisPool;            @Override            public void run(String... strings) throws Exception {                Jedis jedis= jedisPool.getResource();                try {                    //监听所有reids通道中的过期事件                    jedis.psubscribe(new Subscribe(), "*");                } catch (Exception e) {                    jedis.close();                    e.printStackTrace();                }finally {                    jedis.close();                }            }        }

4、具体业务中向redis中添加key
/**         * 添加redis秒定时任务         * @param seconds 秒         */        private void addRedisTimer(String key,int seconds) {            Jedis jedis = jedisPool.getResource();            try {                if (!jedis.exists(key))                    jedis.setex(key,seconds,"");            }catch (Exception e){                logger.error("addRedisTimer error: ", e);            }finally {                jedis.close();            }        }

这样我们就实现了springboot已启动就开启一个线程用来监听reids的keyspace notifications事件,然后接收到事件后处理相应的业务代码

0 0
原创粉丝点击