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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)

背景简介

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

  • 异步数据处理:比如先将订单入库,每分钟扫描未支付的订单做批处理。
  • 自动化运维:比如每小时清理一次数据库的历史记录。
  • 系统监控:比如每分钟扫描监控指标,如果超出阈值,进行报警。
  • 数据同步:比如每天凌晨 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 依赖完成接入。

xml

代码解读

复制代码

<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 依赖

xml

代码解读

复制代码

<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 配置(如果已经添加可以忽略这步)

ini

代码解读

复制代码

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:

less

代码解读

复制代码

@SpringBootApplication
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "3m")
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

创建定时任务:

kotlin

代码解读

复制代码

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] 提出关于分布式定时任务的业务功能诉求和建议。


作者:阿里云云原生

链接:https://juejin.cn/post/7402173730239037474

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
15天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
22天前
|
消息中间件 自然语言处理 Java
知识科普:Spring Cloud Alibaba基本介绍
知识科普:Spring Cloud Alibaba基本介绍
55 2
|
29天前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
30天前
|
人工智能 Java API
阿里云开源 AI 应用开发框架:Spring AI Alibaba
近期,阿里云重磅发布了首款面向 Java 开发者的开源 AI 应用开发框架:Spring AI Alibaba(项目 Github 仓库地址:alibaba/spring-ai-alibaba),Spring AI Alibaba 项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。本文将详细介绍 Spring AI Alibaba 的核心特性,并通过「智能机票助手」的示例直观的展示 Spring AI Alibaba 开发 AI 应用的便利性。示例源
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
3月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
107 2
基于Redis的高可用分布式锁——RedLock
|
3月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
6天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
40 16
|
1月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
57 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
1月前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
47 1