
第一步:pom.xml
org.springframework.boot
spring-boot-starter-data-redis
第二步:application.yml
server:
port: 8081
servlet:
context-path: /
spring:
# redis非关系型数据库
redis:
host: 服务器ip
port: 6379
password: 密码
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 500
# 连接池中的最小空闲连接
min-idle: 0
lettuce:
shutdown-timeout: 0
第三步:DelayTask延时任务模型
/**
* @Author ben
* @Description 延时任务模型
* @Date 上午10:59 2022/3/4
**/
@Data
public class DelayTask {
/**
* 消息id
*/
private String id;
/**
* 任务名称
*/
private String taskName;
/**
* 具体任务内容
*/
private T msg;
}
第四步:RedisDelayQueue延时队列
/**
* @Author ben
* @Description redis延时队列
* @Date 上午11:05 2022/3/4
**/
public class RedisDelayQueue {
/**
* 延迟队列名称
*/
private String delayQueueName = "delayQueue";
private RedisTemplate redisTemplate;
// 传入redis客户端操作
public RedisDelayQueue(RedisTemplate redisTemplate, String delayQueueName)
{
this.redisTemplate = redisTemplate;
this.delayQueueName = delayQueueName;
}
/**
* 设置延迟消息
*/
public boolean setDelayTasks(T msg, long delayTime) {
DelayTask delayTask = new DelayTask<>();
delayTask.setId(UUID.randomUUID().toString());
delayTask.setMsg(msg);
Boolean addResult = redisTemplate.opsForZSet().add(delayQueueName, JSONObject.toJSONString(delayTask), System.currentTimeMillis() + delayTime);
if(addResult)
{
System.out.println("添加任务成功!"+JSONObject.toJSONString(delayTask)+"当前时间为"+ LocalDateTime.now());
return true;
}
return false;
}
/**
* 监听延迟消息
*/
public void listenDelayLoop() {
System.out.println("线程名称:"+ Thread.currentThread().getName());
System.out.println("线程id:"+ Thread.currentThread().getId());
while (true) {
// 获取一个到点的消息
Set set = redisTemplate.opsForZSet().rangeByScore(delayQueueName, 0, System.currentTimeMillis(), 0, 1);
// 如果没有,就等等
if (set.isEmpty()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 继续执行
continue;
}
// 获取具体消息的key
String it = set.iterator().next();
// 删除成功
if (redisTemplate.opsForZSet().remove(delayQueueName, it) > 0) {
// 拿到任务
DelayTask delayTask = JSONObject.parseObject(it, DelayTask.class);
// 后续处理
System.out.println("消息到期;"+delayTask.getMsg().toString()+",到期时间为"+ DateUtil.formatAsDatetime(new Date()));
}
}
}
}
第五步:CustomerThread 消费者线程
/**
* @Classname CustomerThread
* @Description 消费者线程
* @Date 2022/3/4 23:38
* @Created ben
*/
public class CustomerThread extends Thread {
private RedisTemplate redisTemplate;
public CustomerThread(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
}
@Override
public void run(){
RedisDelayQueue queue = new RedisDelayQueue(redisTemplate,"下单未付款,1min后自动取消!");
queue.listenDelayLoop();
}
}
第六步:RedisController延时任务入口
/**
* @Classname RedisController
* @Description redis延时任务入口
* @Date 2022/3/4 22:41
* @Created ben
*/
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisTemplate redisTemplate;
public boolean customerThread = false;
@RequestMapping("/createDelayTasks")
public CommonResult createDelayTasks(@RequestParam(value = "orderNumber") String orderNumber){
String msg = "订单号:" + orderNumber + ",下单时间:"+ DateUtil.formatAsDatetime(new Date());
RedisDelayQueue queue = new RedisDelayQueue(redisTemplate,"下单未付款,1min后自动取消!");
boolean result = queue.setDelayTasks(msg, 60000);
if (!customerThread){
customerThread = true;
CustomerThread thread = new CustomerThread(redisTemplate);
thread.start();
}
if (result){
return new CommonResult(true,"下单成功,未付款,1min后自动取消订单!");
}
return new CommonResult(false,"下单失败!");
}
}
第七步:CommonResult公共返回对象
/**
* @Author ben
* @Description 公共返回对象
* @Date 上午11:40 2022/1/14
**/
@Data
public class CommonResult implements Serializable {
private boolean isucceed;
private T data;
public CommonResult(boolean isucceed,T data) {
this.isucceed = isucceed;
this.data = data;
}
public CommonResult(){
}
}
第八步:install
- install后的jar包,就在项目路径的target下.

第九步:部署服务器,并启动项目
- 部署此处省略,可参考(51条消息) 服务器--阿里轻量应用服务器部署springboot项目_卷神一代的博客-CSDN博客_轻量应用服务器部署springboot
https://blog.csdn.net/weixin_51110874/article/details/122469932?spm=1001.2014.3001.5501
第十步:访问url,并测试
- ip:端口号/redis/createDelayTasks?orderNumber=1
