最近我在对项目的定时任务服务升级,希望改造成分布式,原本是利用@Scheduled注解实现,然而它并不支持分布式,如果改成quartz或者Spring Cloud Task,感觉对于自己这个简单的项目也没有必要。因此,我准备手写一个简单的支持分布式定时调度任务的框架。

项目地址是https://github.com/death00/dis-schedule,欢迎大家star、提意见。

分析

先分析了一下自己的项目,全都是用的cron表达式,因此执行时间点都是固定的,如果升级为分布式的话,肯定是希望在同一个时间点只有一个应用去执行定时调度。

场景就变成了:

多个应用在同一个时间都尝试去执行任务,但最终只有一个应用真正执行。

这样的话,立马就会让人联想到使用去解决,因为是多个应用,所以就是分布式锁。那么,场景又变了:

多个应用在同一个时间都尝试去获取分布式锁,只有一个应用能抢到这把锁,抢到锁的应用可以执行定时任务,其他应用则直接放弃,等待下一次执行时间。

抢锁的时机是每次定时任务执行之前,这又让我联想到了AOP,那么利用注解也就顺理成章了。

分布式锁

既然谈到了分布式锁,那么就想一下,这把锁的名称构成是什么。因为定时任务都有自己专门的时间,如果仅仅采用时间的话,那么当有两个任务同时执行时,则就是在抢一把锁,这同样是不合理的。

所以,锁的名称由两部分组成:任务执行时间、任务名称。

实现

实现方案其实已经很成熟了,可以利用Redis数据库Zookeeper等,Redis用的命令是setNx数据库一般都是利用的唯一索引Zookeeper这点我也不是很了解(如果有感兴趣的同学,欢迎在我的项目中添加)。

我的项目中实现了Redis数据库两种方式,可以看类DisScheduleRedisServiceImplDisScheduleMongodbServiceImpl

注解

其次,我自定义了一个注解DisSchedule

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DisSchedule { /**
* 定时调度任务的名称(默认是方法名)
*/
String name() default ""; /**
* 任务的间隔时间
*/
int duration(); /**
* duration的时间单位(默认:分钟)
*/
DisScheduleUnit unit() default DisScheduleUnit.MINUTES;
}
  1. name代表此次定时调度任务的名称。
  2. duration代表任务的间隔时间,配合unit
  3. unit是自定义的时间单位,有秒、分钟。

该注解需要配合@Scheduled共同使用,例如:

    @DisSchedule(name = "testSchedule", duration = 1, unit = DisScheduleUnit.MINUTES)
@Scheduled(cron = "0 0/1 * * * ?")

cron表达式代表1分钟执行一次,且是在整数分钟开始的时候执行,因此@DisSchedule也需要设置为1分钟的时间。

切面

接下来,我们只需要在Aspect中定义好切入点(有注解@DisSchedule的方法上),针对这些方法,需要使用Around(环绕增强)进行拦截,因为当抢不到锁的时候,就不允许执行。

具体可以参考类DisScheduleAspect

总结

以上就是我实现的简单的分布式定时任务,虽然简单,但应该可以满足你的基础需求,接下来,我会在这个之上,逐步增加功能(比如监测、失败后预警等)。如果你有什么想法,欢迎在下方留言。

有兴趣的话可以访问我的博客或者关注我的公众号、头条号,说不定会有意外的惊喜。

https://death00.github.io/

升级@Scheduled-分布式定时任务的更多相关文章

  1. 【redis】分布式锁实现,与分布式定时任务

    如果你还不知道redis的基本命令与基本使用方法,请看 [redis]redis基础命令学习集合 写在前面 redis辣么多数据结构,这么多命令,具体一点,都可以应用在什么场景呢?用来解决什么具体的问 ...

  2. springboot整合xxl-job分布式定时任务【图文完整版】

    一.前言 定时任务有很多种,有一些大的框架也有一些简单的实现. 比如常见的: JDK的Timer和TimerTask Quartz异步任务调度框架 分布式定时任务XXL-JOB Spring Task ...

  3. spring的Scheduled(定时任务)和多线程

    一.前言 在我们日常的开发中,经常用到数据同步的更新,这时我们采用的是spring的定时任务和java的多线程进行数据的更新,进行时实的服务调用. 二.实现思路            1.创建线程类 ...

  4. 基于spring+quartz的分布式定时任务框架

    问题背景 我公司是一个快速发展的创业公司,目前有200人,主要业务是旅游和酒店相关的,应用迭代更新周期比较快,因此,开发人员花费了更多的时间去更=跟上迭代的步伐,而缺乏了对整个系统的把控 没有集群之前 ...

  5. spring注解scheduled实现定时任务

    只想说,spring注解scheduled实现定时任务使用真的非常简单. 一.配置spring.xml文件 1.在beans加入xmlns:task="http://www.springfr ...

  6. 分布式定时任务框架比较,spring batch, tbschedule jobserver

    分布式定时任务框架比较,spring batch, tbschedule jobserver | 移动开发参考书 分布式定时任务框架比较,spring batch, tbschedule jobser ...

  7. lesson9:分布式定时任务

    在实际的开发过程中,我们一定会遇到服务自有的定时任务,又因为现在的服务都是分布式的,但是对于定时任务,很多的业务场景下,还是只希望单台服务来执行,网上有很多分布式定时任务的框架,各位如感兴趣,可以自行 ...

  8. 分布式定时任务 -- elastic-job

    一.前言 在我们的项目当中,使用定时任务是避免不了的,我们在部署定时任务时,通常只部署一台机器.部署多台机器时,同一个任务会执行多次.比如短信提醒,每天定时的给用户下发短信,如果部署了多台,同一个用户 ...

  9. 分布式定时任务框架——python定时任务框架APScheduler扩展

    http://bbs.7boo.org/forum.php?mod=viewthread&tid=14546 如果将定时任务部署在一台服务器上,那么这个定时任务就是整个系统的单点,这台服务器出 ...

  10. 【xxl-job】轻松实现分布式定时任务demo实例

    [项目描述]前段时间专门独立了一个spring boot服务,用于做和第三方erp系统的对接工作.此服务的第一个需求工作就是可以通过不同的规则,设置不同的定时任务,从而获取erp系统的商品数据.所以, ...

随机推荐

  1. js数组的五种迭代遍历方式 every filter forEach map some

    ECMAScript 5 为数组定义了 5 个迭代方法. 每个方法都接收两个参数   数组项的值和索引 every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 tru ...

  2. c3p0,dbcp与druid 三大连接池的区别[转]

    说到druid,这个是在开源中国开源项目中看到的,说是比较好的数据连接池.于是乎就看看.扯淡就到这. 下面就讲讲用的比较多的数据库连接池.(其实我最先接触的是dbcp这个) 1)DBCP DBCP是一 ...

  3. [转]Android中设置TextView的颜色setTextColor

    [转自]http://txlong-onz.iteye.com/blog/1249609 Android中设置TextView的颜色setTextColor android中设置TextView的颜色 ...

  4. bzoj 1051 [HAOI2006]受欢迎的牛(tarjan缩点)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 题解:缩点之后判断出度为0的有几个,只有一个那么输出那个强连通块的点数,否者 ...

  5. "ANDROID" 支持的KEYCODE

      例子: adb shell input text keyevent 4 0 -->  "KEYCODE_UNKNOWN" 1 -->  "KEYCODE_ ...

  6. WPF 字体图标样式

    1.在网上下载Font ICO 字体字体压缩包 Font Awesome 矢量图标库    2.下载到的压缩包,解压后获得图标字体文件        3.然后把字体文件夹拷贝到项目中,目录为(/fon ...

  7. 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入

    简介 依赖注入主要是一种结构性的模式,注重的是类与类之间的结构,它要达到的目的就是设计原则中最少知道和合成复用的原则,减少内部依赖,履行单一职责,最终就是强解耦.依赖注入目前最好的实现就是依赖注入容器 ...

  8. 《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性

    IM 系统中,保证消息的可靠投递主要体现在两方面,一是消息的不丢失,二是消息的不重复. 一.消息不丢失 消息丢失的原因 首先看一下发送消息的流程,如下图所示: 消息.可以采取"时间戳比对&q ...

  9. 几个Python爬虫工具介绍

    Request Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用 上面一句话 出自Requests官方文档的第一句,从而奠定了其逗逼的文档风格.类似的还有: 警告: ...

  10. 卸载VMware

    最近使用ubuntu的时候操作不当直接卡死了,然后强制关闭VMware软件,之后再打开时出现本文中的 “Vmware启动ubuntu 出现错误 ”这个情况,具体请看链接:https://www.cnb ...