使用Redis+SpringBoot实现定时任务

首先,Redis实现定时任务是基于对RedisKey值的监控

具体代码实现:

代码GitHub地址:
  • 建一个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业务不做处理");
		}
	}
}
  • 演示:

定时成功!!

 


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!