延时任务通知服务的设计及实现(二)-- redisson的延迟队列RDelayedQueue

一、接着上文

RDelayedQueue作为redisson封装的一个分布式延迟队列,直接拿来使用还是比较简单的。

本文主要包括以下几部分:

  • 保存至延迟队列(生产者)
  • 读取延迟队列(消费者)
  • 从延迟队列移除任务

二、redission配置

bash 复制代码
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Redisson配置类
 *
 * @author xxx
 */
@Configuration
public class RedissonConfig {
    @Value("${spring.application.name}")
    private String serverName;

    @Bean
    public RedissonClient redissonClient(RedisProperties redisProperties) {
        Config config = new Config();
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
        singleServerConfig.setPassword(redisProperties.getPassword());
        singleServerConfig.setKeepAlive(true);
        singleServerConfig.setDatabase(redisProperties.getDatabase());
        singleServerConfig.setConnectionMinimumIdleSize(2);
        singleServerConfig.setConnectionPoolSize(4);
        singleServerConfig.setClientName(serverName);
        return Redisson.create(config);
    }
}
bash 复制代码
spring:
  application:
    name: delay-task-service
  redis:
    host: 192.168.8.18
    port: 6379
    database: 0
    timeout: 3000

三、保存至延迟队列(生产者)

作为延迟任务的生产者,你需要根据预期的回调时间,计算出delay延迟时间。

伪代码见下:

java 复制代码
public static final  String REDISSON_QUEUE_NAME = "DelayTaskQueue";

private final RedissonClient redissonClient;

RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue(REDISSON_QUEUE_NAME);
RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

long delay = DateUtil.between(event.getNotifyDate(), new DateTime(), DateUnit.SECOND);

delayedQueue.offer(event.getTransNo(), delay < 0 ? 1 : delay, TimeUnit.SECONDS);

四、读取延迟队列(消费者)

java 复制代码
    public static final  String REDISSON_QUEUE_NAME = "DelayTaskQueue";

    private final RedissonClient redissonClient;
    
    @PostConstruct
    public void init() {
        new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>())
                .execute(() -> {
                    while (true) {
                        try {
                            RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque(REDISSON_QUEUE_NAME);
                            RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);

                            String transNo = blockingDeque.take();

                            if (null == transNo) {
                                return;
                            }

                            if (log.isInfoEnabled()) {
                                log.info("开始执行延迟队列中的任务,transNo={}", transNo);
                            }
                            // 异步执行你的操作
                            notifyTaskService.handleTask(transNo, null);
                        } catch (Exception e) {
                            log.error("延时队列的任务执行出现异常", e);
                        }
                    }
                });
    }

五、从延迟队列移除任务

java 复制代码
public static final  String REDISSON_QUEUE_NAME = "DelayTaskQueue";

private final RedissonClient redissonClient;

RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue(REDISSON_QUEUE_NAME);
RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

delayedQueue.remove(transNo);

六、总结

本文主要是摘要一些源码,仅供参考。

附:相关系列文章链接

延时任务通知服务的设计及实现(一)-- 设计方案

延时任务通知服务的设计及实现(二)-- redisson的延迟队列RDelayedQueue

延时任务通知服务的设计及实现(三)-- JDK的延迟队列DelayQueue

延时任务通知服务的设计及实现(四)-- webhook执行任务

相关推荐
青衫码上行3 分钟前
【从0开始学习Java | 第17篇】集合(中-Set部分)
java·学习
沐雨风栉7 分钟前
自建云音乐服务器:Navidrome+cpolar让无损音乐随身听
运维·服务器·redis·缓存·docker·容器
武子康8 分钟前
Java-122 深入浅出 MySQL CAP理论详解与分布式事务实践:从2PC到3PC与XA模式
java·大数据·数据库·分布式·mysql·性能优化·系统架构
田青钊15 分钟前
Zookeeper核心知识全解:节点类型、集群架构与选举机制
java·分布式·zookeeper
码畜也有梦想16 分钟前
springboot响应式编程笔记
java·spring boot·笔记
0wioiw017 分钟前
Nodejs(④GraphQL)
后端·graphql
王同学 学出来31 分钟前
跟做springboot尚品甄选项目(二)
java·spring boot·后端
bobz96533 分钟前
Calico 项目功能分析:聚焦转发面
后端
zcz160712782139 分钟前
LVS + Keepalived 高可用负载均衡集群
java·开发语言·算法
bobz9651 小时前
tcp 状态机
后端