Redis超时触发事件
摘要:当设备超过8小时未上线时发送短信通知管理员,由于设备数据通过redis维护,使用Timer实现时。将Timer缓存到redis中再取出的时候,Timer获取不到。
参考资料:【redis高级功能-超时触发事件】--
https://www.jianshu.com/p/92b331355b8d
1、redis服务器配置
超时的监听,并不需要自己发布,只需修改配置文件redis.conf中的:
notify-keyspace-events ""
改为
notify-keyspace-events Ex
改完之后的配置文件:
相关的配置说明:
中文说明:
# K 键空间通知,以__keyspace@<db>__为前缀 # E 键事件通知,以__keyevent@<db>__为前缀 # g del , expipre , rename 等类型无关的通用命令的通知, ... # $ String命令 # l List命令 # s Set命令 # h Hash命令 # z 有序集合命令 # x 过期事件(每次key过期时生成) # e 驱逐事件(当key在内存满了被清除时生成) # A g$lshzxe的别名,因此”AKE”意味着所有的事件
修改好配置文件后,redis会对设置了expire的数据进行监听,当数据过期时便会将其从redis中删除。
2、监听程序
public class KeyExpiredListener extends JedisPubSub { @Override public void onPSubscribe(String pattern, int subscribedChannels) { System.out.println("onPSubscribe " + pattern + " " + subscribedChannels); } @Override public void onPMessage(String pattern, String channel, String message) { System.out.println("onPMessage pattern " + pattern + " " + channel + " " + message); } }
3、订阅程序
public class Subscriber { public static void main(String[] args) { JedisPool pool = new JedisPool(new JedisPoolConfig(), "192.168.1.100",6379,60000,"123456"); Jedis jedis = pool.getResource(); //只订阅patten匹配在超时事件 jedis.psubscribe(new KeyExpiredListener(), "__key*@0__:expired"); } }
4、测试类
public class TestJedis { public static void main(String[] args) { JedisPool pool = new JedisPool(new JedisPoolConfig(), "192.168.1.100",6379,60000,"123456"); Jedis jedis = pool.getResource(); jedis.select(0); jedis.set("notify", "你还在吗"); jedis.expire("notify", 10); jedis.select(1); jedis.set("test","test"); jedis.expire("test", 20); } }
5、测试结果
运行订阅程序Subscriber
运行测试类TestJedis
说明:redis数据库分为0-15共16个库,默认使用0数据库,测试程序中jedis.select(n)为选择数据库。Subscriber控制台只监听了0库的过期时间,因为订阅程序设置了匹配pattern为__key*@0__:expired的。
订阅pattern和channel可以参考:【Redis订阅与发布】