Redis拓展之定时消息通知实现详解

 更新时间:2023年07月05日 09:53:23   作者:右耳菌  
这篇文章主要为大家介绍了Redis拓展之定时消息通知实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

1. Redis实现定时消息通知

简单定时任务通知: 利用redis的keyspace notifications(即:键过期后事件通知机制)

开启方法

  • 修改server.conf文件,找到notify-keyspace-events , 修改为“Ex”
  • 使用cli命令: redis-cli config set notify-keyspace-events Ex
  • redis 配置参考

2. 例子

创建springboot项目

修改pom.xml 和 yml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.9</version> <!-- 这个版本其实还是挺重要的,如果是2.7.3版本的话,大概会无法成功自动装载 RedisConnectionFactory -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.lazyfennec</groupId>
    <artifactId>redisdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redisdemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml

spring:
  redis:
    database: 0
    host: 192.168.1.7
    port: 6379
    jedis:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1

创建RedisConfig

package cn.lazyfennec.redisdemo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/9/20 23:19
 */
@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate&lt;String, Object&gt; redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer&lt;Object&gt; jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer&lt;Object&gt;(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate&lt;String, Object&gt; redisTemplate = new RedisTemplate&lt;&gt;();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer); // key 序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value 序列化
        redisTemplate.setHashKeySerializer(stringSerializer); // Hash key 序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // Hash value 序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }  
}

创建RedisListenerConfiguration

package cn.lazyfennec.redisdemo.config;
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.listener.RedisMessageListenerContainer;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/9/21 11:02
 */
@Configuration
public class RedisListenerConfiguration {
    @Autowired
    private RedisConnectionFactory factory;
    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer() {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(factory);
        return redisMessageListenerContainer;
    }
}

事件监听事件 RedisTask

package cn.lazyfennec.redisdemo.task;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/9/21 11:05
 */
@Component
public class RedisTask extends KeyExpirationEventMessageListener {
    public RedisTask(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 接收到事件后回调
        String channel = new String(message.getChannel(), StandardCharsets.UTF_8);
        String key = new String(message.getBody(), StandardCharsets.UTF_8);
        System.out.println("key:" + key + ", channel:" + channel);
    }
}

发布 RedisPublisher

package cn.lazyfennec.redisdemo.publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/9/21 16:34
 */
@Component
public class RedisPublisher {
    @Autowired
    RedisTemplate<String, Object> redisTemplate;
    // 发布
    public void publish(String key) {
        redisTemplate.opsForValue().set(key, new Random().nextInt(200), 10, TimeUnit.SECONDS);
    }
    // 循环指定时间触发
    @Scheduled(cron = "0/15 * * * * ?")
    public void scheduledPublish() {
        System.out.println("scheduledPublish");
        redisTemplate.opsForValue().set("str1", new Random().nextInt(200), 10, TimeUnit.SECONDS);
    }
}
  • 要实现Scheduled需要在启动类上加上注解
@SpringBootApplication
@EnableScheduling // 要加上这个,用以启动
public class RedisdemoApplication {

修改TestController

package cn.lazyfennec.redisdemo.controller;
import cn.lazyfennec.redisdemo.publisher.RedisPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/9/21 16:32
 */
@RestController
public class TestController {
    @Autowired
    RedisPublisher redisPublisher;
    @GetMapping("/redis/{key}")
    public String publishEvent(@PathVariable String key) {
        // 发布事件
        redisPublisher.publish(key);
        return "OK";
    }
}

以上就是Redis拓展之定时消息通知实现详解的详细内容,更多关于Redis定时消息通知的资料请关注脚本之家其它相关文章!

相关文章

  • 详解Redis实现限流的三种方式

    详解Redis实现限流的三种方式

    这篇文章主要介绍了详解Redis实现限流的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Redis深入了解内存淘汰与事务操作

    Redis深入了解内存淘汰与事务操作

    将Redis用作缓存时,Redis数据存在内存中,如果内存空间用满,就会自动驱逐老的数据。Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
    2022-07-07
  • redis key命名规范的设计

    redis key命名规范的设计

    如果结构规划不合理、命令使用不规范,会造成系统性能达到瓶颈、活动高峰系统可用性下降,也会增大运维难度,本文主要介绍了redis key命名规范的设计,感兴趣的可以了解一下
    2024-03-03
  • 利用redis实现排行榜的小秘诀

    利用redis实现排行榜的小秘诀

    这篇文章主要给大家介绍了关于如何利用redis实现排行榜的小秘诀,文中通过示例代码介绍的非常详细,对大家学习或者使用redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • 在redhat6.4安装redis集群【教程】

    在redhat6.4安装redis集群【教程】

    这篇文章主要介绍了在redhat6.4安装redis集群【教程】,需要的朋友可以参考下
    2016-05-05
  • Redis分布式锁解决超卖问题的使用示例

    Redis分布式锁解决超卖问题的使用示例

    超卖问题通常出现在多用户并发操作的情况下,即多个用户尝试购买同一件商品,导致商品库存不足或者超卖,本文就来介绍一下超卖问题,感兴趣的可以了解一下
    2023-09-09
  • redis服务器允许远程主机访问的方法

    redis服务器允许远程主机访问的方法

    今天小编就为大家分享一篇redis服务器允许远程主机访问的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Redis源码解析sds字符串实现示例

    Redis源码解析sds字符串实现示例

    这篇文章主要为大家介绍了Redis源码解析sds字符串实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • redis实现分布式延时队列的示例代码

    redis实现分布式延时队列的示例代码

    延时队列是一种特殊的消息队列,它允许将消息在一定的延迟时间后再进行消费,延时队列的实现方式可以有多种,本文主要来介绍一种redis实现的分布式延时队列,希望对大家有所帮助
    2023-10-10
  • 一文详解Redis中的持久化

    一文详解Redis中的持久化

    这篇文章主要介绍了一文详解Redis中的持久化,持久化功能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复
    2022-09-09

最新评论