目录
应用场景
redis 2.8.0之后版本提供允许客户发布订阅Pub/Sub功能
当前应用于订单发货后15天自动确认收货,订单支付倒计时等,需考虑消息丢失,重复等问题
事件类型
以keyspace为前缀的频道为键空间通知
以keyevent为前缀的频道为键事件通知
代码实现
一、注意事项
需要使用过期key监听事件需要开启配置,否则无法生效
二、配置方法
第一种:命令行配置:CONFIG set notify-keyspace-events Ex 缺点重启可能失效需重新运行此命令,不推荐
第二种:文件配置:修改redis配置文件redis.conf
三、测试
1. 开启第一个客户端
psubscribe __keyevent@*__:expired
2. 打开第二个客户端发送消息
3. 客户端二发送消息,两秒后,客户端一成功接收到消息
四、代码实现
import cn.hutool.core.util.StrUtil; import co.yixiang.listener.RedisKeyExpirationListener; import co.yixiang.modules.activity.service.YxStorePinkService; import co.yixiang.modules.order.service.YxStoreOrderService; import co.yixiang.modules.user.service.YxUserLevelService; import co.yixiang.utils.RedisUtils; import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * redis监听配置 * @author 小郭 * @since 2020-11-03 */ @Configuration @AllArgsConstructor public class RedisListenerConfig { @Autowired private RedisKeyExpirationListener redisMessageListener; @Bean public ChannelTopic expiredTopic() { //监听数据库索引15 return new ChannelTopic("__keyevent@15__:expired"); } @Bean public RedisMessageListenerContainer redisMessageListenerContainer( @Autowired RedisConnectionFactory redisConnectionFactory) { RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); redisMessageListenerContainer.addMessageListener(redisMessageListener, expiredTopic()); return redisMessageListenerContainer; } public static void main(String[] args) { System.out.println(1111); JedisPool pool = new JedisPool(new JedisPoolConfig(), "redis主机名",6379,5000,"redis密码",redis索引名); Jedis jedis = pool.getResource(); //设置一个5秒钟的过期时间 jedis.setex("type+订单号id", 5,"发送消息100"); System.out.println(2222); } } import cn.hutool.core.util.StrUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Component; /** * redis过期监听 * @author 小郭 * @since 2020-02-27 */ @Component @Slf4j public class RedisKeyExpirationListener implements MessageListener { @Autowired private RedisTemplate<String, String> redisTemplate; @Override //key 过期时调用 public void onMessage(Message message, byte[] pattern) { System.out.println("onPMessage pattern " + pattern + " " + " " + message); String channel = new String(message.getChannel()); String str = (String) redisTemplate.getValueSerializer().deserialize(message.getBody()); System.out.println(str); } }
五、代码测试
发送消息
接收到消息