Spring Cloud Alibaba 集成分布式定时任务调度功能

ops/2024/9/24 3:50:52/

作者:千习

背景简介

定时任务是指在约定的时间,或者按照固定频率周期性执行的任务。在企业应用中,非用户行为发起的后台业务,一般都是通过定时任务来实现,常见场景如下:

  • 异步数据处理:比如先将订单入库,每分钟扫描未支付的订单做批处理。
  • 自动化运维:比如每小时清理一次数据库的历史记录。
  • 系统监控:比如每分钟扫描监控指标,如果超出阈值,进行报警。
  • 数据同步:比如每天凌晨 1 点把 mysql 中的数据同步到大数据平台中。

在单体应用中,实现定时任务很简单,比如 Java 中有 java.util.Timer 和 ScheduledExecutorService。在 Spring 框架中也提供了 scheduling 方便的开发定时任务。但是在微服务中,一个应用一般来说有很多节点,通过以上实现方式,就会带来一个致命的问题,那就是任务重复执行。

在这里插入图片描述

Spring Cloud Alibaba 发布了 Scheduling 任务调度 [ 1] 模块 [#3732] [ 2] 提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。

微服务下的分布式任务能力

定时任务功能作为应用开发中重要能力之一,在 Spring Framework [ 3] 中提供了对定时任务支持,在其最基础的使用场景下可方便的通过 @Scheduled 注解轻松的开发出一个定时任务【剖析参考 [ 4] 】;也可以通过扩展集成 Quartz 框架来实现部分分布式能力,但其目前无法方便的通过 spring 的 @Scheduled 注解快速地定义一个任务。框架原生提供的这些能力在单体应用场景下够用,但在微服务分布式集群场景下就显得有些力所不能及了。

因此在 Spring Cloud Alibaba 体系中我们希望提供一个模块能力,能在微服务场景下快速接入使用分布式定时任务能力。分布式定时任务应该具备哪些能力特性,参考如下对比。

在这里插入图片描述

在微服务分布式场景中,除了基础的定时任务运行能力,还需提供如:防重复执行、分片运行、任务执行并行度控制等能力,后续还可在此基础上继续探索定时任务对微服务应用服务本身的定时调度支持,欢迎在社区提出需求和建议。

快速接入体验

在新版的 Spring Cloud Alibaba 版本中提供分布式任务调度快速启动模块 spring-cloud-starter-alibaba-schedulerx 来支持各类分布式定时任务方案集成。对于采用了 Spring Cloud Alibaba 的微服务应用可以通过添加如下 pom 依赖完成接入。

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-schedulerx</artifactId><version>{version}</version>
</dependency>

在应用配置文件提供了 spring.cloud.scheduling.distributed-mode 参数让用户选择采用哪一种实现方案,目前提供了基于“阿里云 schedulerx”和“开源 shedlock”两种模式。后续可根据社区用户需求继续增加其他方案的接入。更为具体详细的接入说明可参考:Example 示例工程 [ 5]

采用阿里云 SchedulerX

接入 Spring 分布式定时任务,最简单的方式就是直接接入阿里云托管的分布式任务调度平台 SchedulerX [ 6] ,不但完全兼容 Spring @Scheduled 注解,还具有高可用、高安全、高性能、免运维、低成本等特点。

任务调度平台 SchedulerX 的任务管理平台,可以帮助您动态新增、修改、运维定时任务,还有报警监控、历史记录、日志服务、链路追踪等企业级可观测方案,同时还可获得如任务分片执行等增强能力,为应用线上定时任务稳定运行保驾护航。

在这里插入图片描述

接入步骤
  1. 登录 SchedulerX 控制台 [ 7] ,免费开通服务。

  2. 参考接入文档 [ 8] 接入,每个账号拥有 5 个免费任务额度,可先 0 成本试用体验。

在这里插入图片描述

采用本地开源方式

不借助云产品,本地接入方式可以再结合 @SchedulerLock [ 9] 注解来实现分布式定时任务。

@SchedulerLock 注解是一个分布式锁的框架,结合 @Scheduled 注解,可以保证任务同一时间,在多个节点上只会执行一次。该框架支持多种分布式锁的实现,比如 Jdbc、Zookeeper、Redis 等,目前的集成模块中只提供了 Jdbc 的方案,后续会继续新增其他模式来满足用户现有场景架构所需。其原理如下:

在这里插入图片描述

接入步骤

下面以 Mysql 分布式锁为例,演示分布式任务的接入过程,首先需要按本章节开始说明添加 spring-cloud-starter-alibaba-schedulerx 和对应配置参数,除此之外用户还需完成如下配置:

  1. 由于采用 jdbc 作为分布式锁实现,因此还需如下 pom 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
  1. 在 application.properties 文件中添加 jdbc 配置(如果已经添加可以忽略这步)
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class=com.mysql.cj.jdbc.Driver

完成上述配置启动应用后,会在对应数据库中创建一个 shedlock 表用于定时任务的执行同步处理。

应用程序代码及任务示例参考如下:

配置启动类,启用 SchedulingTasks:

@SpringBootApplication
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "3m")
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

创建定时任务:

import org.joda.time.DateTime;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;@Component
public class SpringJob {/*** 每5分钟跑一次*/@Scheduled(cron = "0 */5 * * * ?")@SchedulerLock(name = "SpringJob.job1", lockAtMostFor = "2m", lockAtLeastFor = "1m")public void job1() {System.out.println("time=" + DateTime.now().toString("YYYY-MM-dd HH:mm:ss") + " do job1...");}/*** 每5秒跑一次*/@Scheduled(fixedRate = 5000)@SchedulerLock(name = "SpringJob.job2", lockAtMostFor = "4s", lockAtLeastFor = "4s")public void job2() {System.out.println("time=" + DateTime.now().toString("YYYY-MM-dd HH:mm:ss") + " do job2...");}/*** 上次跑完之后隔5秒再跑* @throws InterruptedException */@Scheduled(fixedDelay = 5000)@SchedulerLock(name = "SpringJob.job3", lockAtMostFor = "4s", lockAtLeastFor = "4s")public void job3() throws InterruptedException {System.out.println("time=" + DateTime.now().toString("YYYY-MM-dd HH:mm:ss") + " do job3...");Thread.sleep(10000);}
}

未来规划

Spring Cloud Alibaba 分布式定时调度模块为微服务应用场景提供了快速集成接入解决方案,后续可为更多分布式定时任务实现方案提供快速集成,比如:继续集成 quartz/xxljob 等开源组件,且让上述开源组件也都能来适配 spring 的 @Scheduled 注解,实现一份任务代码可对接不同调度服务;同时也会为分布式任务场景下所需的业务能力提供扩展支持。欢迎大家给开源社区 [ 10] 提出关于分布式定时任务的业务功能诉求和建议。

相关链接:

[1] Scheduling 任务调度

https://sca.aliyun.com/docs/2023/user-guide/schedulerx/quick-start/

[2] [#3732]

https://github.com/alibaba/spring-cloud-alibaba/pull/3732

[3] Spring Framework

https://docs.spring.io/spring-framework/docs/5.3.37/reference/html/integration.html#scheduling

[4] 剖析参考

https://developer.aliyun.com/article/1015756

[5] Example 示例工程

https://github.com/alibaba/spring-cloud-alibaba/blob/2023.x/spring-cloud-alibaba-examples/spring-cloud-scheduling-example/README.md

[6] 分布式任务调度平台 SchedulerX

https://www.aliyun.com/ntms/middleware/schedulerx

[7] SchedulerX 控制台

https://schedulerx2.console.aliyun.com/public/AppList

[8] 接入文档

https://help.aliyun.com/zh/schedulerx/user-guide/spring-jobs?spm=5176.14256785.help.dexternal.f09e126dAXAvEs#p-9sy-0ay-hgx

[9] @SchedulerLock

https://github.com/lukas-krecan/ShedLock

[10] 开源社区

https://sca.aliyun.com/


http://www.ppmy.cn/ops/93390.html

相关文章

【商城小程序系统的功能实现】

文章目录 前言一、商品展示二、搜索与过滤三、购物车四、下单与支付五、评价与反馈六、订单管理七、会员系统八、优惠券与促销活动九、库存管理十、数据分析总结 前言 商城小程序系统的功能实现通常包括以下几个方面&#xff1a; 一、商品展示 在小程序中展示商品的详细信息&…

初识云计算

随着科技的飞速发展&#xff0c;云计算作为一种新兴的信息技术架构&#xff0c;正在逐渐改变我们的工作方式和生活方式。 云计算是什么&#xff1f; 云计算是一种通过互联网提供计算资源和服务的计算模式。它通过互联网将计算和存储资源进行集中和共享&#xff0c;为用户提供…

计算机毕业设计选题推荐-电缆行业生产管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

PyTorch库学习之torch.chunk函数

PyTorch库学习之torch.chunk函数 一、简介 torch.chunk 是 PyTorch 库中的一个函数&#xff0c;它用于将一个多维张量分割成多个较小的张量&#xff0c;每个张量在指定的维度上大小相同。这个函数在处理数据时非常有用&#xff0c;尤其是在需要将数据分成多个批次或进行并行处…

C++_基本语法笔记_继承和多态

继承 思想与Java差不多 基本语法 语法&#xff1a;class 子类 : 继承方式 父类 继承方式 将访问权限&#xff0c;上升到保护权限&#xff0c;上升到更高的私有权限 继承哪些部分 继承过程中&#xff0c;即使权限不能访问&#xff0c;也会全部继承下来&#xff08;非静…

Android12修改系统默认语言

系统一般都是默认英文的&#xff0c;如果设置系统中文那怎么修改呢 方案一 默认中文 Change-Id: I18dc21ce9abb3a1175b875a5e…

Java三表联查方法

有些数据的查询需要我们查询三个表来获得总的数据。 一、准备工作&#xff1a; 我前面写过两表联查的方式&#xff0c;三表联查就是在两表联查的基础上进行的&#xff0c;下面是我写的两表联查博客 三表查询和两表查询的区别就只是在配置文件里的映射文件不一样&#xff0c;…

Zookeeper的监听机制

Zookeeper的监听机制是Zookeeper框架中一个至关重要的功能&#xff0c;它实现了分布式系统中数据状态变化的实时通知&#xff0c;使得客户端能够及时响应并处理这些变化。下面将详细解析Zookeeper的监听机制及其原理&#xff0c;包括监听器的注册、事件通知的处理、监听器的特点…