首页 > 其他分享 >常见的定时任务方案

常见的定时任务方案

时间:2024-07-16 18:30:31浏览次数:16  
标签:方案 常见 param delayTime springframework import org 定时 public

常见的延时任务方案

1、最轻量级(基于内存的线程池实现)一般用于短时间实时性较高,容许少量消息丢失


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.*;

@Slf4j
@Component
public class MessageSender {

    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    public void sendMessageWithDelay(String message, long delayInSeconds) {
        scheduler.schedule(() -> {
            try {
                log.info("数据消息补偿,message={},delayTime={}",message,delayInSeconds);
                //todo 做业务操作
            }catch (Exception e){
                log.error("数据消息补偿,brand={},orderNo={}",message,delayInSeconds,e);
            }
        }, delayInSeconds, TimeUnit.SECONDS);
    }
}

2、轻量级(基于Redission的实现)推荐 一般用于实时性,消息可靠性,轻量级的综合选择

引入依赖

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.9.1</version>
        </dependency>

消息发布器


import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@Component
public class RedissionDelayMessageSender {

    private final RedissonClient redissonClient;
    /**
     *  发布延时消息
     *  @param param
     *  @param delayTime
     */
    public void publishDelayMsg(JSONObject param,long delayTime) {
        RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque("delay-channel-queue");
        RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
        int retryNum = Integer.parseInt(String.valueOf(param.getOrDefault("retryNum", "0"))) + 1;
        log.info("当前回调重试次数={}", retryNum);
        param.put("retryNum", String.valueOf(retryNum));
        param.put("msg", param.getString("msg"));
        delayedQueue.offer(param.toJSONString(), delayTime, TimeUnit.SECONDS);
        log.info("延时消息发送成功,delayTime={},data={}", delayTime, param);
    }
}

消息处理器


import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: MsgHandler
 * @Author: lmy
 * @Description:
 * @Version: 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RedissionDelayMessageHandler {

    private final RedissonClient redissonClient;
    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @PostConstruct
    public void startListener() {
        threadPoolTaskExecutor.execute(this::handle);
    }

    public void handle(){
        RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque("delay-channel-queue");
        while (true) {
            try {
                String data = blockingDeque.poll(2, TimeUnit.SECONDS);
                log.info("监听到延迟消息:{}", data);
                if (StringUtils.isNotBlank(data)) {
                    JSONObject jsonObject = JSONObject.parseObject(data);
                    int retryNum = Integer.parseInt(String.valueOf(jsonObject.getOrDefault("retryNum", "0")));
                    if (retryNum < 3){
                        jsonObject.put("retryNum",retryNum);
                        //todo 做业务
                    }else {
                        log.warn("重试已达最大次数3,退出重试,人工介入,param={}",data);
                    }
                }
            } catch (Exception e){
                log.error("监听延迟发布消息失败", e);
            }
        }
    }
}

3、消息可靠性高(基于MQ技术实现的延时消息)推荐 一般用于消息可靠性较高,不允许丢失


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author:
 */
@Slf4j
@Component
public class RabbitMqDelayMessageSender {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @RabbitHandler
    @RabbitListener(queues = "queue-name")
    public void listener(JSONObject entity, Channel channel, Message message) throws IOException {
        String databaseName = entity.getString("database");
        String tableName = entity.getString("table");
        JSONArray data = entity.getJSONArray("data");
        //todo 做业务
        sendDelayMessage(data.toJSONString(), 10000L);
        //消息手动签收
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
    
    /**
     * 发送延迟消息
     *
     * @param msg 消息体
     * @param delayTime  延迟时间
     */
    public void sendDelayMessage(String msg, Long delayTime) {
        rabbitTemplate.convertAndSend("delay-exchange", "delay-key", msg, message -> {
            //默认接收毫秒
            message.getMessageProperties().setHeader("x-delay", delayTime);
            return message;
        });
        log.info("延迟消息发送成功,data={},delayTime={},",msg,delayTime );
    }
}

4、消息可靠性较高(基于定时任务轮询实现的数据库持久化)
这个比较简单,自己实现吧

标签:方案,常见,param,delayTime,springframework,import,org,定时,public
From: https://www.cnblogs.com/ceilingZ/p/18305869

相关文章

  • 服务器上数据定时同步到网络磁盘
    背景:由于权限问题无法将网络磁盘直接挂载到HPC上,但是可以挂载到本地,解决思路是通过rsyncd进行同步,每次同步的时候都将网络磁盘挂载到本地。我想把服务器上/home/s222552331/LUTO2_XH/Custom_runs/下的文件同步到网络磁盘的z/LUF-Modelling/LUTO2_XH/LUTO2/output一、Window本地操......
  • 智能守护校园餐桌:校园阳光食堂视频AI监控智能管理方案
    一、背景分析随着科技的飞速发展,智能化、信息化已成为现代校园管理的重要趋势。校园食堂作为学校重要的服务设施,其食品安全、环境卫生和秩序管理显得尤为重要。作为校园生活中不可或缺的一部分,食堂的管理也急需引入先进技术,以提高食品安全、提升服务质量、优化就餐环境。为此,我们......
  • 园区道路车辆智能管控视频解决方案,打造安全畅通的园区交通环境
    一、背景需求分析随着企业园区的快速发展和扩张,道路车辆管理成为了保障园区秩序、提升运营效率及确保员工安全的重要任务。针对这一需求,旭帆科技TSINGSEE青犀提出了一种企业园区道路车辆管控的解决方案,通过整合视频监控、智能识别等技术,实现园区内车辆的有序管理,提升安全管理水平......
  • Oracle常见数据块损坏处理方式
    1前提:备份数据库查看数据库的模式SYS@orcl>selectopen_mode,log_modefromv$database;OPEN_MODE LOG_MODE--------------------------------READWRITE ARCHIVELOG修改RMAN的备份参数RMAN>configurecontrolfileautobackupon;newRMANconfigur......
  • 智慧煤矿:AI视频智能监管解决方案引领行业新变革
    随着科技的飞速发展,人工智能(AI)技术已经渗透到各个行业,为传统产业的转型升级提供了强大的动力。在煤矿行业中,安全监管一直是一个重要的议题。为了提高煤矿的安全生产水平,降低事故发生率,智慧煤矿的概念应运而生,它结合了先进的AI智能监管技术,为煤矿的安全生产、高效运营和可持续发展......
  • 无人机区域常见名词
    融合空域是指有其他航空器同时运行的空域。隔离空域是指专门分配给无人机系统运行的空域,通过限制其他航空器的进入以规避碰撞风险。人口稠密区是指城镇、村庄、繁忙道路或大型露天集会场所等区域。重点地区是指军事重地、核电站和行政中心等关乎国家安全的区域及周边,或......
  • Visual Studio使用——vs使用过程中常见问题积累,技巧集锦等,持续更新中
    目录引出VisualStudio使用自定义代码片段vs显示所有文件总结Idea安装和使用0.Java下载和IDEA工具1.首次新建项目2.隐藏文件不必要显示文件3.目录层级设置4.Settings设置选择idea的场景提示代码不区分大小写取消git的代码作者显示引出VisualStudio使用——vs......
  • 存储系列DAS,SAN,NAS常见网络架构
    随着主机、磁盘、网络等技术的发展,对于承载大量数据存储的服务器来说,服务器内置存储空间,或者说内置磁盘往往不足以满足存储需要。因此,在内置存储之外,服务器需要采用外置存储的方式扩展存储空间,今天在这里我们分析一下当前主流的存储架构。一、DASDirectAttachedStorage,直接连......
  • iOS开发基础102-后台保活方案
    iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码:一、后台任务利用beginBa......
  • RDMA 高性能架构基本原理与设计方案
    RDMA的主要优点包括低延迟、高吞吐量、减少CPU负担和支持零拷贝网络。它允许数据直接在网络接口卡(NIC)和内存之间传输,减少了数据传输过程中的中间环节,从而显著降低了延迟。RDMA技术能够实现高速的数据传输,适用于需要大量数据交换的应用场景。由于数据传输不需要CPU的参与,CPU可......