RabbitMQ实现定时任务

发布时间:2026/7/30 12:33:19

RabbitMQ实现定时任务 首先我们要理解下什么是异步「异步」Asynchronous是程序执行的一种方式核心特点是发起一个任务后不用等待它完成就能继续执行后面的代码。同步对比理解你点外卖一直盯着手机等骑手接单啥也不干直到骑手确认接单才去做别的事。异步你点外卖后不用等接单直接去看书 / 追剧等骑手接单了系统发通知你再看一眼手机。编程里的异步就是这个逻辑比如调用一个「读取文件」的异步方法程序不会卡在 “等文件读完” 这一步而是继续执行后面的代码等文件真的读完了再通过「回调 / 事件 / 协程」等方式处理结果。这就是同步代码public class SyncDemo { public static void main(String[] args) { System.out.println(开始执行); // 模拟耗时操作比如读取大文件、调用远程接口 doLongTask(); // 这里会阻塞必须等这个方法执行完才会打印下面的内容 System.out.println(继续执行后续代码); } // 模拟耗时5秒的同步任务 private static void doLongTask() { try { Thread.sleep(5000); // 阻塞5秒 System.out.println(耗时任务完成); } catch (InterruptedException e) { e.printStackTrace(); } } }这就是同步代码的输出开始执行 等待5秒 耗时任务完成 继续执行后续代码然后这是异步import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; public class AsyncDemo { public static void main(String[] args) throws InterruptedException { System.out.println(开始执行); // 异步执行耗时任务不用等它完成 CompletableFuture.runAsync(() - doLongTask()) .whenComplete((v, e) - { // 任务完成后触发的回调异步处理结果 if (e null) { System.out.println(异步任务执行成功); } else { System.out.println(异步任务出错 e.getMessage()); } }); // 主线程继续执行不会被阻塞 System.out.println(继续执行后续代码); // 防止主线程提前退出仅示例实际业务无需死等 TimeUnit.SECONDS.sleep(6); } private static void doLongTask() { try { Thread.sleep(5000); System.out.println(耗时任务完成); } catch (InterruptedException e) { e.printStackTrace(); } } }他的输出则是开始执行 继续执行后续代码 等待5秒 耗时任务完成 异步任务执行成功异步就是非阻塞而同步则是按照执行顺序会有阻塞异步是同时发生同步则是按顺序现在我们理解一下什么是定时任务这常常用到Spring 框架的 Scheduled 注解简单场景和Quartz 框架复杂场景。定时任务是后端开发中非常基础且高频的功能本质是在指定时间 / 频率自动执行预设逻辑几乎所有中大型 Java 项目都会用到。作用这类任务主要处理数据的同步、清理、统计、归档是定时任务最基础也最常用的场景。使用场景1. 数据清理 / 过期数据删除清理 Redis 中过期的缓存如验证码、临时 token删除数据库中超过保留期的数据如日志表、临时订单、用户浏览记录清理服务器上的临时文件如上传的未处理图片、日志文件。2. 数据同步 / 异构数据更新跨系统数据同步如电商系统将订单数据同步到仓储系统、财务系统数据库与缓存同步如定时将数据库热点数据加载到 Redis保证缓存最新第三方数据拉取如定时调用快递接口更新物流状态、调用支付接口同步订单支付结果。3. 数据统计 / 报表生成生成日 / 周 / 月报表如电商的日销售额、用户新增数、商品销量排行计算业务指标如用户留存率、复购率、接口调用成功率数据汇总如将分表数据汇总到总表方便后续分析使用一Scheduled最常用适合执行频率固定、逻辑简单的定时任务前置条件Spring Boot 项目确保你的项目中引入了 Spring Context 相关依赖Spring Boot Starter Web/Starter 都已包含无需额外引入依赖。import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; // 1. 启动类添加EnableScheduling注解开启定时任务功能 SpringBootApplication EnableScheduling public class ScheduledTaskApplication { public static void main(String[] args) { SpringApplication.run(ScheduledTaskApplication.class, args); } } // 2. 定义定时任务组件 Component class MyScheduledTasks { // 方式1固定频率执行每隔5秒执行一次从上一次执行结束开始计时 Scheduled(fixedRate 5000) public void fixedRateTask() { System.out.println(固定频率任务执行 LocalDateTime.now()); } // 方式2固定延迟执行每隔3秒执行一次从上一次执行开始计时 Scheduled(fixedDelay 3000) public void fixedDelayTask() { System.out.println(固定延迟任务执行 LocalDateTime.now()); } // 方式3Cron表达式最灵活例每分钟的第10秒执行 // Cron表达式格式秒 分 时 日 月 周 年年可选 Scheduled(cron 10 * * * * ?) public void cronTask() { System.out.println(Cron表达式任务执行 LocalDateTime.now()); } }二使用Quartz 框架复杂场景如动态添加 / 删除任务、任务持久化、分布式调度1. 引入依赖Spring Bootdependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-quartz/artifactId /dependency2. 完整实现代码import org.quartz.*; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.quartz.QuartzJobBean; import java.time.LocalDateTime; SpringBootApplication public class QuartzTaskApplication { public static void main(String[] args) { SpringApplication.run(QuartzTaskApplication.class, args); } // 1. 定义Quartz任务类 public static class MyQuartzJob extends QuartzJobBean { Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // 获取任务参数 String taskName context.getJobDetail().getJobDataMap().getString(taskName); System.out.println(Quartz任务执行 taskName 时间 LocalDateTime.now()); } } // 2. 配置JobDetail任务详情 Bean public JobDetail myJobDetail() { // 传入任务参数设置任务持久化即使没有触发器关联也不会被删除 return JobBuilder.newJob(MyQuartzJob.class) .withIdentity(myJob, myJobGroup) .usingJobData(taskName, 测试Quartz任务) .storeDurably() .build(); } // 3. 配置Trigger触发器定义执行规则 Bean public Trigger myTrigger() { // 每10秒执行一次 SimpleScheduleBuilder scheduleBuilder SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) .repeatForever(); return TriggerBuilder.newTrigger() .forJob(myJobDetail()) .withIdentity(myTrigger, myTriggerGroup) .withSchedule(scheduleBuilder) // 也可以用Cron表达式CronScheduleBuilder.cronSchedule(0 0 3 * * ?) .build(); } }注意事项Spring 的 Scheduled 默认使用单线程执行所有定时任务若任务执行时间过长会导致任务阻塞。可通过配置线程池优化Configuration public class ScheduledConfig { Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); // 核心线程数 scheduler.setThreadNamePrefix(scheduled-task-); return scheduler; } }定时任务中必须捕获所有异常否则任务执行失败后会终止后续执行Scheduled(cron 10 * * * * ?) public void cronTask() { try { // 业务逻辑 System.out.println(任务执行 LocalDateTime.now()); } catch (Exception e) { // 记录日志 System.err.println(任务执行失败 e.getMessage()); } }

相关新闻