Redis實現定時任務是基於對RedisKey值的監控
具體代碼實現:
代碼GitHub地址:https://github.com/Tom-shushu/Project
- 建一個SpringBoot項目
- 引入依賴
<?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.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>redistask</artifactId> <version>0.0.1-SNAPSHOT</version> <name>redistask</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.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> </plugin> </plugins> </build> </project>
- 配置文件
spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.timeout=10000
- 新建一個配置類
package com.zhouhong.redistask.redistaskconfig; 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; /** * description: Redis配置類 * @author: zhouhong * @version: V1.0.0 * @date: 2021年3月19日 上午10:58:24 */ @Configuration public class RedisTaskConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
- 新建Controller,設置不同過期時間的Key值,注意這里key值最好使用當前的業務標識做前綴,不然可能出現key重復的現象。
package com.zhouhong.redistask.redistaskcontroller; import java.util.Date; import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * description: 測試Redis定時Controller類 * @author: zhouhong * @version: V1.0.0 * @date: 2021年3月19日 上午10:59:21 */ @RestController public class RedisTaskController { @Autowired private RedisTemplate< String, String> template; Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME); /** * 設置定時key,這里key最好使用業務前綴,防止名字相同 * @return */ @RequestMapping(value = "putkeys", method = RequestMethod.POST) public String putRedisTaskKeys() { Date date = new Date(); logger.info("業務開始時間:" + date); String key10S = "business1"+"|"+"key10S"+"|"+"其他業務中需要使用到的參數"; String key20S = "business1"+"|"+"key20S"+"|"+"其他業務中需要使用到的參數"; template.opsForValue().set(key10S, "values", 10, TimeUnit.SECONDS); template.opsForValue().set(key20S, "values", 20, TimeUnit.SECONDS); return "RedisKey過期鍵設置成功"; } }
- 新建Service用來監控過期Key,並且針對不同時間做不同的業務
package com.zhouhong.redistask.service; import java.util.Date; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; 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 org.springframework.stereotype.Service; /** * description: RedisKey鍵監聽以及業務邏輯處理 * @author: zhouhong * @version: V1.0.0 * @date: 2021年3月19日 上午10:58:52 */ @Service @Component public class RedisTaskService extends KeyExpirationEventMessageListener { Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME); /** * @param listenerContainer */ public RedisTaskService(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 將拿到的過期鍵使用之前拼接時的特殊符號分割成字符數組 String[] expiredKeyArr = expiredKey.split("\\|"); String businessSign = expiredKeyArr[0].toString(); String expiredTimeSign = expiredKeyArr[1].toString(); String othersParm = expiredKeyArr[2].toString(); logger.info(businessSign + expiredTimeSign + othersParm); Date date = new Date(); // 只有本業務才執行以下操作 if (businessSign.equals("business1")) { if (expiredTimeSign.equals("key10S")) { // 定時十秒鍾后業務處理 logger.info("十秒鍾時的時間:"+ date); logger.info("定時任務10秒鍾已到,下面處理相關業務邏輯代碼!!!"); logger.info("10秒鍾后的業務邏輯代碼,其他業務參數" + othersParm); } else if (expiredTimeSign.equals("key20S")) { // 定時十秒鍾后業務處理 logger.info("二十秒鍾時的時間:"+ date); logger.info("定時任務20秒鍾已到,下面處理相關業務邏輯代碼!!!"); logger.info("20秒鍾后的業務邏輯代碼,其他業務參數" + othersParm); } } else { logger.error("非business1業務不做處理"); } } }
- 演示:
定時成功!!