定时任务 订阅
定时任务是一款系统安全类软件,支持Android 2.1。 展开全文
定时任务是一款系统安全类软件,支持Android 2.1。
信息
应用名称
定时任务
应用版本
0.3
运行环境
Android 2.1
应用平台
mobile
应用类型
系统安全类
三维重建简介
Timed Tasks是一款Wi-Fi、飞行模式、蓝牙、数据连接、屏幕亮度定时开关任务软件,让各项设置按自己所设的时间、日期开启或关闭。
收起全文
精华内容
下载资源
问答
  • 定时任务
    千次阅读
    2022-03-14 09:40:39

    SpringBoot实现用户定制的定时任务(动态定时任务)

    情景

      我们知道SpringBoot能使用@Scheduled注解来进行定时任务的控制,该注解需要配合Cron表达式以及在启动类上添加@EnableScheduling注解才能使用。
      不过我们现在的假定情景并不是程序员设定的定时任务,而是用户可以在我们的网页上定制定时任务,前端将该任务的信息发送到后端后,后端可以将此任务存入数据库并在规定的时间内执行。例如用户可以设定定时任务的执行时间段,执行时刻等,并可以随时新增、删除和改变定时任务。
      接下来我们来使用SpringBoot实现这个假定情景

    实现

    实体类Cron

      我们需要创建实体类Cron代表定时任务,这里假设Cron有如下属性:执行时刻、任务标题、任务开始的日期、任务截止日期,以及存入数据库所需要的几个基本属性:id(作为主键)、创建时间、更新时间、状态status
      我们用一个BaseEntity来保存基本属性,Cron将继承BaseEntity,使用MyBatisPlus作为ORM框架,Cron的代码如下:

    @Data
    @EqualsAndHashCode(callSuper = true)
    public class Cron extends BaseEntity {
    
    	private static final long serialVersionUID = 1L;
    
    	@NotNull(message = "执行时刻不能为空")
    	private LocalTime executeTime;
    
    	@NotBlank(message = "标题不能为空")
    	private String title;
    
    	@NotNull(message = "截止日期不能为空")
    	private LocalDate deadTime;
    
    	@NotNull(message = "开始日期不能为空")
    	private LocalDate startTime;
    	
    }
    

      这里需要注意的是lombok的@Data注解相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。
      其中,@EqualsAndHashCode注解会生成equals(Object other) 和 hashCode()方法。我们重写了equals(Object other) 和 hashCode()方法,就是为了在两个对象的属性相同时equals能返回true,认为它们两个相同。但@EqualsAndHashCode默认仅使用该类中定义的属性且不会调用父类的equals(Object other) 和 hashCode()方法。这是什么意思呢?仅使用该类中的属性,也就是如果该类的两个对象属性相同,即使这两个对象对应父类的属性不同,equals也会认为它们两个对象相同,从而返回true。默认的实现中不使用父类的属性,将会导致问题,比如,有多个类有相同的部分属性,恰好id(数据库主键)在父类中,那么就会存在部分对象在比较时,它们并不相等,却因为lombok自动生成的equals(Object other) 和 hashCode()方法判定为相等,从而导致出错。所以我们在使用@Data时同时需要加上@EqualsAndHashCode(callSuper=true)注解来解决这一问题,加上(callSuper=true),其生成的equals(Object other) 和 hashCode()方法将调用父类的方法,也就是会考虑父类的属性。
      加上@EqualsAndHashCode(callSuper=true)就符合我们的要求了,这样即使两个Cron对象,它们的属性相同,但它们在父类中对应的主键不同,equals将认为它们是不同的对象,返回false。

      对于前端传参,我们需要进行非空验证,我们在实体类中还加入了@NotNull和@NotBlank注解,并且使用message配置提示语句。这两个注解都来自于javax.validation.constraints包,该包内还有另一个常用注解@NotEmpty,@NotEmpty 用在集合上面,一般用来校验List类型(不能注释枚举类型),而且长度必须大于0。@NotBlank 用在String上面,一般用来校验String类型不能为空,而且调用trim()后,长度必须大于0。@NotNull 可用在所有类型上,校验是否为非null。这些注解都需要配合@Validated注解使用,从而检验Controller的入参是否符合规范,例如:

    public Result save(@Validated @RequestBody Cron cron)
    

      Cron的父类BaseEntity的代码如下:

    @Data
    public class BaseEntity implements Serializable {
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
        private LocalDateTime created;
        private LocalDateTime updated;
        private Integer status;
    }
    

      由于实体类需要在网络中传输,所以BaseEntity需要实现Serializable接口,这里使用MyBatisPlus的@TableId注解进行属性与数据库主键的映射。

    Service层:接口CronService以及其实现类CronServiceImpl

      我们需定义接口CronService来实现用户定制定时任务需求。用户能创建、删除、修改定时任务,创建任务即判断当前日期是否为既定的执行日期,若是则启动定时任务。删除任务即判断该任务是否已被启动,若是,则将其停止。修改任务即先停止该任务,再重新启动该任务。我们让CronService继承MyBatisPlus的IService接口,对应的数据库操作直接在Controller层中调用相应方法即可,我们就不需要再在CronService中定义了。于是,我们需要在CronService中定义startCron(Cron cron)stopCron(Cron cron)changeCron(Cron cron)三个方法,分别对应用户的创建、删除、修改定时任务操作。

    public interface CronService extends IService<Cron> {
    
    	void startCron(Cron cron);
    
    	void stopCron(Cron cron);
    
    	void changeCron(Cron cron);
    }
    

      我们创建CronService的实现类CronServiceImpl来实现上述3个方法。
      对于每个定时任务,我们肯定是让线程池提供一个线程去执行它,springboot提供了ThreadPoolTaskScheduler,可以很方便地对重复执行的任务进行调度管理;相比于通过java自带的周期性任务线程池ScheduleThreadPoolExecutorThreadPoolTaskScheduler支持根据cron表达式创建周期性任务,这正是我们所需要的。其实ThreadPoolTaskScheduler底层也是通过线程池ScheduleThreadPoolExecutor实现的,不过多加了一些支持Cron表达式的代码。ThreadPoolTaskScheduler的核心成员变量是ScheduledExecutorService scheduledExecutor,一个 ExecutorService 可以安排任务在给定的延迟后运行,或者定期执行。ScheduledFuture表示可以取消的延迟结果动作。 通常,ScheduledFuture是使用 ScheduledExecutorService 执行任务的返回结果。

      因此,我们使用ThreadPoolTaskScheduler来启动线程,执行定时任务。但这还不够,我们有很多定时任务,我们必须保存它们的信息,以便查找,因为我们还有停止任务和更新任务操作。于是我们可以创建一个HashMap来保存定时任务的信息,key肯定是cron的id,value为ScheduledExecutorService 执行任务的返回结果ScheduledFuture。我们可以调用ScheduledFuturecancel方法来终止任务的执行。

      接下来我们来考虑CronService接口3个方法的具体实现。对于startCron方法,我们需要避免它重复启动已经启动的任务,因此我们要先判断该任务是否已经在HashMap中,若不在,我们再去判断当前日期是否在执行日期范围内,若在,我们通过Cron的执行时刻属性构造cron表达式,创建实现了Runnable接口的内部类来实现任务要做的事,调用ThreadPoolTaskSchedulerschedule方法启动该任务,并将该任务存入HashMap中。
      对于stopCron方法,我们通过Cron的id从HashMap中查找其对应的ScheduledFuture,若不为空,则调用其cancel(true)方法停止任务,并将其从HashMap中删除。cancel方法的参数传入true会中断线程停止任务,而传入false则会让线程正常执行至完成。
      changeCron方法的实现很简单,先调用stopCron,再调用startCron即可

      CronServiceImpl的完整代码如下:

    @Service
    public class CronServiceImpl extends ServiceImpl<CronMapper, Cron> implements CronService {
    
    	private Logger log = LoggerFactory.getLogger(getClass());
    
    	@Autowired
    	private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    
    	private Map<Long, ScheduledFuture<?>> futureMap = new HashMap<>();
    
    	@Bean
    	public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    		return new ThreadPoolTaskScheduler();
    	}
    
    	@Override
    	public void startCron(Cron cron) {
    		if (futureMap.containsKey(cron.getId())) {
    			log.warn("已经存在重复任务,任务id:{},任务标题:{},任务提醒时刻:{},任务开始时间:{},任务截止时间:{}",
    					cron.getId(), cron.getTitle(), cron.getExecuteTime(), cron.getStartTime(), cron.getDeadTime());
    			return;
    		}
    		if (LocalDate.now().isEqual(cron.getStartTime()) || LocalDate.now().isEqual(cron.getDeadTime()) ||
    				(LocalDate.now().isAfter(cron.getStartTime()) && LocalDate.now().isBefore(cron.getDeadTime()))) {
    			LocalTime executeTime = cron.getExecuteTime();
    			String cronExp = StringUtils.join(Integer.valueOf(executeTime.getSecond()).toString(), " ", Integer.valueOf(executeTime.getMinute()).toString()
    					, " ", Integer.valueOf(executeTime.getHour()).toString(), " * * ?");
    			ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(new MyRunnable(cron), new CronTrigger(cronExp));
    			futureMap.put(cron.getId(), future);
    			log.info("启动定时任务成功,任务id:{},任务标题:{},任务提醒时刻:{},任务开始时间:{},任务截止时间:{}",
    					cron.getId(), cron.getTitle(), cron.getExecuteTime(), cron.getStartTime(), cron.getDeadTime());
    		}
    	}
    
    	@Override
    	public void stopCron(Cron cron) {
    		ScheduledFuture<?> future = futureMap.get(cron.getId());
    		if (future != null) {
    			future.cancel(true);
    			futureMap.remove(cron.getId());
    			log.info("关闭定时任务成功,任务id:{},任务标题:{},任务提醒时刻:{},任务开始时间:{},任务截止时间:{}",
    					cron.getId(), cron.getTitle(), cron.getExecuteTime(), cron.getStartTime(), cron.getDeadTime());
    		}
    
    	}
    
    	@Override
    	public void changeCron(Cron cron) {
    		stopCron(cron);// 先停止,在开启.
    		startCron(cron);
    	}
    	
    	private class MyRunnable implements Runnable {
    
    		private Cron cron;
    
    		public MyRunnable(Cron cron) {
    			this.cron = cron;
    		}
    
    		@Override
    		public void run() {
    			// 定义任务要做的事,完成任务逻辑
    
    		}
    	}
    }
    

      其实我们这样做还没有完成需求,因为在startCron中,只有当前时间在执行时间段内,才会创建线程去执行定时任务,这样是肯定不行的。我们还需要创建一个定时任务管理器,让它每天定时去启动数据库中尚未启动的定时任务,并删除已经过期的定时任务,防止数据积压。

    定时任务管理器CronManageTask

      这时我们就需要用@Scheduled注解了,我们定义CronManageTask中的cronManage()方法,加上@Scheduled注解,让它每天定时去启动数据库中尚未启动的定时任务,并停止并删除已经过期的定时任务。
      使用@Scheduled注解需要注意几个点,一是CronManageTask需使用@Component注解,且此类中不能包含其他带任何注解的方法;二是cronManage()方法不能有参数、不能有返回值;三是需添加@EnableScheduling注解到启动类上面。
      违反上述任一点,@Scheduled注解就不会生效

      CronManageTask的代码如下:

    @Component
    public class CronManageTask {
    
    	private Logger log = LoggerFactory.getLogger(getClass());
    
    	@Autowired
    	private CronService cronService;
    
    	@Scheduled(cron = "0 0 3 * * ?")
    	public void cronManage() {
    		List<Cron> list = cronService.list();
    		list.forEach(c -> {
    			if (LocalDate.now().isAfter(c.getDeadTime())) {
    				cronService.stopCron(c);
    				cronService.removeById(c.getId());
    				log.info("删除过期定时任务成功,任务id:{},任务标题:{},任务提醒时刻:{},任务开始时间:{},任务截止时间:{}",
    						c.getId(), c.getTitle(), c.getExecuteTime(), c.getStartTime(), c.getDeadTime());
    			} else {
    				log.info("尝试启动尚未start的定时任务,任务id:{},任务标题:{},任务提醒时刻:{},任务开始时间:{},任务截止时间:{}",
    						c.getId(), c.getTitle(), c.getExecuteTime(), c.getStartTime(), c.getDeadTime());
    				cronService.startCron(c);
    			}
    		});
    	}
    }
    

      cron表达式"0 0 3 * * ?"表示每天凌晨3点执行。需要注意的是,@Scheduled注解的cron表达式一般都要定义在配置文件里,方便修改,使用cron = "${xiaolinbao.cron}",并在application.yml中配置xiaolinbao.cron=0 0 3 * * ?即可。上面的代码偷懒了。

      至此,使用SpringBoot实现动态定时任务的需求就完成了

    更多相关内容
  • C#实现的自定义定时任务 可定时运行 多任务运行
  • Java多线程之定时任务 以及 SpringBoot多线程实现定时任务、以及分享动态实现定时任务 1. 基于单线程的定时器——简单介绍 Timer 中的 schedule 与 scheduleAtFixedRate 2. 基于多线程的定时器——...

    1. 基于单线程的定时器——简单介绍 Timer 中的 schedule 与 scheduleAtFixedRate

    1.1 前言

    • Timer,一般是用来做延时的任务或者循环定时执行的任务。
      使用 Timer 的时候,必须要有一个 TimerTask 去执行任务,这是一个实现了Runnable接口的线程,run 方法里面就是我们自己定义的线程需要做的任务。

    1.2 先说 schedule

    • 我们简单说4种情况,其实也就两个重载方法:
    • timer.schedule(timerTask,0);,没用延迟,立即执行task,且只执行一次,线程还在。 代码和效果直接看图
      在这里插入图片描述
    • timer.schedule(timerTask,5000);,延迟5秒执行task,且只执行一次,线程还在。代码和效果直接看图
      在这里插入图片描述
    • timer.schedule(timerTask,0,60000);,0表示没用延迟,立即执行,然后60000表示每隔1分钟执行一次task。代码和效果直接看图
      在这里插入图片描述
    • timer.schedule(timerTask,5000,60000);,延迟5秒后执行task,然后每隔1分钟执行一次task,代码和效果直接看图:
      在这里插入图片描述

    附代码:

    package com.liu.susu.thread.task.timer;
    
    import java.time.LocalDateTime;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * @FileName TimeTaskTest1
     * @Description
     * @Author susu
     * @date 2022-03-07
     **/
    public class TimerTaskTest1 {
        public static void main(String[] args) {
            Timer timer = new Timer();
            TimerTask timerTask = new TimerTask() {//TimerTask 是实现 Runnable 接口的一个线程
                @Override
                public void run() {
                    System.out.println("task-->hello world!-->"+LocalDateTime.now());
                }
            };
            System.out.println("begin-->"+LocalDateTime.now());
    
    //        timer.schedule(timerTask,0);//没用延迟,立即执行task,且只执行一次,线程还在
    //        timer.schedule(timerTask,5000);//延迟5秒执行task,,且只执行一次,线程还在
    //        timer.schedule(timerTask,0,60000);//0表示没用延迟,立即执行,然后60000表示每隔1分钟执行一次task
            timer.schedule(timerTask,5000,60000);//延迟5秒后执行task,然后每隔1分钟执行一次task
        }
    }
    
    

    1.3 schedule 与 scheduleAtFixedRate 的区别

    • 关于上述介绍的 schedule 的4种调用情况,scheduleAtFixedRate 同样也有,最终效果也是一致的,我们这里就不介绍了,说说它两不一样的地方。什么时候不一样呢?当给他们设置指定开始任务的时间时,它们的区别就有了。
      主要是 public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 方法 与 public void schedule(TimerTask task, Date firstTime, long period) 方法的区别。
    • 我们先看官网怎么说的:
      在这里插入图片描述
      在这里插入图片描述
    • 如果不是很明白看我们下面的效果图:
      在这里插入图片描述
      在这里插入图片描述

    小结

    • void schedule(TimerTask task, Date firstTime,long period)方法的任务的计划执行时间是从第一次实际执行任务开始计算的。
      如果执行任务的时间没有被延时,那么下一次任务的执行时间参考上一次任务的“开始”时的时间来计算
    • scheduleAtFixedRate 会计算首次调用时间,在执行时会先计算出错过的时间内 task 应执行的次数,再去按设定频率去执行。
    • 具体原理,还需要大家看源码分析!

    附代码

    package com.liu.susu.thread.task.timer;
    
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.format.DateTimeFormatter;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * @FileName TimerTaskTest2
     * @Description
     * @Author susu
     * @date 2022-03-07
     **/
    public class TimerTaskTest2 {
        public static void main(String[] args) {
            Timer timer = new Timer();
            TimerTask timerTask = new TimerTask() {
                @Override
                public void run() {
                    System.out.println("task-->"+ LocalDateTime.now());
                }
            };
            Date firstDateTime = getFirstDateTime();
            System.out.println("firstDateTime-->"+firstDateTime+"<=====>now-->"+LocalDateTime.now()+"\n");
            timer.schedule(timerTask,firstDateTime,10000);
            timer.scheduleAtFixedRate(timerTask,firstDateTime,10000);
        }
        public static Date getFirstDateTime(){
            String dateStr = "2022-03-07 16:30:34";
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime localDateTime = LocalDateTime.parse(dateStr, dateTimeFormatter);
            Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
            return date;
        }
    
    }
    
    

    2. 基于多线程的定时器——ScheduledExecutorService

    • ScheduledExecutorService 是一个接口,实现类是ScheduledThreadPoolExecutor,是通过 Executors 自动创建线程池的一种方式(newScheduledThreadPool 方式)
    • 关于线程池的创建可以看:
      详解Java多线程之线程池.
    • 关于 ScheduledThreadPoolExecutor,我们下面就简单说3个方法,完整代码如下:
    package com.liu.susu.thread.task.pool;
    
    import java.time.LocalDateTime;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @FileName ScheduledThreadPoolTest
     * @Description
     * @Author susu
     * @date 2022-03-07
     **/
    public class ScheduledThreadPoolTest {
        public static void main(String[] args) {
            ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
            
            System.out.println("当前时间是-->"+LocalDateTime.now());
            
            //1.schedule--->只延迟执行,且只执行一次(不循环)
            executorService.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()
                            + "-->" + LocalDateTime.now());
                }
            },5,TimeUnit.SECONDS);//推迟5秒执行
    
            //2.scheduleAtFixedRate 推迟执行(initialDelay=0,不推迟),然后周期性循环执行task
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()
                            + "-->" + LocalDateTime.now());
                    try {
                        Thread.sleep(5000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            },5,10,TimeUnit.SECONDS);//推迟5秒执行,然后每10秒执行一次
    
            //3.scheduleWithFixedDelay 推迟执行(initialDelay=0,不推迟),然后周期性循环执行task
            executorService.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()
                            + "-->" + LocalDateTime.now());
                    try {
                        Thread.sleep(5000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            },5,10,TimeUnit.SECONDS);
    
        }
    }
    
    

    2.1 executorService.schedule

    • 创建并执行在给定延迟后启用的单次操作。
    • 效果图:
      在这里插入图片描述
    • 这个没啥可说的了,上面的内容看了的,这个很好理解的,我们主要说一下 scheduleAtFixedRate 与 scheduleWithFixedDelay 的区别。

    2.2 scheduleAtFixedRate 与 scheduleWithFixedDelay 区别

    • 来我们,先看官方怎么说的
      在这里插入图片描述
    • 这是什么意思呢,我们看看下面的效果就非常明白了

    2.2.1 executorService.scheduleAtFixedRate

    • 效果图:
      在这里插入图片描述
    • 上面大概明白怎么走的了吧,区别到底在哪里,先别急,看完下面的效果就明白了!

    2.2.2 executorService.scheduleWithFixedDelay

    • 效果图
      在这里插入图片描述
    • 现在明白二者的区别了吧

    2.2.3 小节

    • scheduleAtFixedRate:是以固定频率来执行线程任务,固定频率的含义就是可能设定的固定间隔时间不足以完成线程任务,但是它不管,达到设定的延迟时间了就要开始执行下一次任务了。
    • scheduleWithFixedDelay:不管线程任务的执行时间的长短,每次都要把任务执行完成后再延迟固定时间(设置的间隔时间)后再执行下一次的任务。

    3. 基于多线程的定时器(SpringBoot)

    3.1 提前了解 cron表达式和@Async异步

    3.2 @EnableScheduling 与 @Scheduled

    • 关于 @EnableScheduling :
      在SpringBoot项目中,在启动类或者定时任务类上添加 @EnableScheduling 注解来开启对定时任务的支持。
    • 关于 @Scheduled :
      如果在定时任务类中的方法上添加 @Scheduled 注解,则该方法是声明需要执行的定时任务。
    • @Scheduled 注解有几种类型参数,先截图下来,我们下面会简单根据例子介绍
      在这里插入图片描述

    3.3 @Scheduled 定时任务例子

    • 首先启动类上添加注解 @EnableScheduling ,下面不再提醒了。
      在这里插入图片描述

    3.3.1 关于 cron 表达式的

    • cron 表达式不是很清楚的,看我们上面提供的链接,此处不做解释了。

    3.3.1.1 cron 例1–>单个任务

    • 用注解 @Scheduled(cron = "0/5 * * * * ?") (每5秒执行一次),代码很简单,直接截图:
      在这里插入图片描述
    • 启动项目后,后台自动按cron表达式配置的执行任务,直接看运行效果:
      在这里插入图片描述
    (1)简单分析@Schedule默认定时任务的线程
    • 观察上面的执行结果,不难发现,Spring 的 Schedule 定时任务默认是单线程的。而且是默认所有定时任务都是在一个线程中执行(下面我们有多任务的例子)!
    • 这样的话,我们看到的只是代码层次的定时任务,而实际执行得过程是一个任务的开启需要等上一个任务的结束才行。尤其是当系统中有特别耗时的定时任务执行频繁的定时任务,执行频繁的任务需要等耗时的任务执行完才能执行,你说这算什么定时任务!
    • 会造成严重得后果就是如果我们有多个定时任务,一个卡死,其他全挂,嗯,就这样。
    • 问题分析出来了,解决是不是就有了,对,异步多线程!

    3.3.1.2 cron 例2–>多个任务(非异步)

    • 用异步前,我们不妨来写两个定时任务看看效果,先看两个耗时都短的任务:
      在这里插入图片描述
      很明显如果耗时短还不好观察,任务1是按定时5秒执行一次,任务2也按定时2秒执行一次,没看出来,但是能看出来是单线程的执行两个任务!。
    • 再来看一个耗时长,一个频繁执行的定时任务,我们让任务1睡一下就行了。
      在这里插入图片描述
      这样对比效果就很明显了吧,这明显不是我们开发中想要的实现方式,所以考虑异步,请往下…

    3.3.1.3 cron 例3–>多个任务(异步@Async)

    • 把上面的例子改成异步试试,很简单啥也不用,直接异步方法上加注解 @Async ,启动类加 @EnableAsync 注解即可。
      再说一下,这两个注解不太了解的,看下面文章,此处不做解释了。
      SpringBoot 自定义线程池以及多线程间的异步调用(@Async、@EnableAsync).
    • 修改后的代码如下(在例子3.3.1.2上修改):
      在这里插入图片描述
    • 效果如图:
      在这里插入图片描述
      可以看到在耗时任务1执行的过程中并不影响任务2定时任务的执行,也不影响任务1自己的定时任务,什么意思,意思就是你可以简单理解为同我们上述2.2.1中介绍的 executorService.scheduleAtFixedRate,即以固定频率来执行线程任务,就是在我们任务1中,设定的固定间隔时间5秒,而5秒不足以完成线程任务(需要10秒完成),但是它不管,达到设定的间隔时间5秒后就要开始执行下一次的任务1了(即:开启新的线程来执行)。

    3.3.1.4 cron 例4–>多个任务(异步@Async——自定义线程池)

    • 3.3.1.3 中,虽然实现了异步,但是 @Async 也存在一个问题,就是默认线程池的问题,这个在这里不做介绍,上面链接的文章里已经说的很清楚,不明白的先了解一下 @Async 。
    • 所以,我们用自定义线程池的方式实现异步定时任务
    • 代码如下(文字代码上面链接介绍异步的文章里都有,这里截图一下看看,明白逻辑就行了):
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    • 效果如下:
      在这里插入图片描述

    3.3.1.5 从配置文件读取 cron表达式 以及停掉 cron任务

    • 用配置文件的形式,主要方便我们以后更改任务的执行时间等。
    • 代码如图:
      在这里插入图片描述
      在这里插入图片描述
    (1)cron 例5–>用符号 “ - ”控制停止定时任务

    注意.properties 与.yml的区别写法

    • ① application.properties 中的 cron 表达式不能用双引号引起,而.yml中可以用双引号引起;
      在这里插入图片描述
      在这里插入图片描述
    • ② 在配置文件里配置让线程任务停掉,不是简单的注释掉,而是用减号符号 “-”,需注意的是两中配置文件写法不一样,yml中必须要加双引号(因为 - 在yml中是一个特殊的字符),application.properties 必须不能用双引号,这点需要注意。
      在这里插入图片描述
      在这里插入图片描述
    (2)cron 例6–>手动控制定时任务的开启和停止
    a. 分析 @EnableScheduling
    • 配置之前,我们先来分析一下源码,为什么启动类上加上 @EnableScheduling 注解就开启了对定时任务的支持了呢?好奇是吧,好奇就点呗,点进去看看…
      在这里插入图片描述
      在这里插入图片描述
      你如果感兴趣的话,可以继续往后点,自己欣赏源码也是打发时间的一种方式,哈哈哈哈!
      快烦了吧,说这么多什么意思呢?意思就是你可以不用这个注解 @EnableScheduling 让定时任务跑起来。怎么跑,先听解释:
    • 其实,任务方法上用的 @Scheduled 注解,是被一个叫做 ScheduledAnnotationBeanPostProcessor (上面最后一张截图里出现的)的类所拦截的,所以,根据源码的实现,我们也可以根据配置,决定是否创建这个 bean,如果有这个 bean ,定时任务正常执行,如果没有这个 bean,@Scheduled 就不会被拦截,那么定时任务肯定不会执行了了,嗯,就是这个道理。请往下看怎么实现:
    a. 配置文件设置定时任务的开关
    • 首先,启动类上的注解 @EnableScheduling 注释掉。
    • 然后,配置文件添加开关,如图:
      在这里插入图片描述
    • 然后,接下来我们说两种方式控制这个bean的创建
    • 方式一:接口 Condition 与注解 Conditional 结合
      在这里插入图片描述
      两种方式说完,我们再测试效果
    • 方式二:直接用注解 @ConditionalOnProperty
      在这里插入图片描述
    • 来,看一下效果吧,定时任务还是那两个任务
      在这里插入图片描述
      在这里插入图片描述
      ok了,就说这么多吧!

    3.3.2 其他类型参数——简单说

    • 如果目录里的 1 和 2 都看明白了,关于 @Scheduled 注解的其他参数真的没什么可说的了,比葫芦画瓢的事了,我们就简单举个例子就行了
      在这里插入图片描述

    4. springboot动态定时任务的实现

    5. 附项目工程代码

    展开全文
  • linux 系统定时任务 服务 详解

    千次阅读 多人点赞 2021-08-18 13:58:03
    定时任务 配置方法2.1定时任务相关文件2.2定时任务编写格式2.3 编写步骤2.4定时任务编写注意事项:(规范)总结 Centos 7 定时服务详解介绍 在企业中,存在很多数据需要备份,那么我们如何让这些数据,每天晚上23:59 ...

    Centos 7 定时服务详解介绍

    在企业中,存在很多数据需要备份,那么我们如何让这些数据,每天晚上23:59 自动备份呢?

    今天呢,我结合部分实践案列,分享一篇关于定时任务的知识点。

    Linux下面有atdcrond两种计划任务,其中,atd服务使用的at命令只能执行一次,而crond服务使用的crontab定义的命令,是循环作用的,所以crond才符合我们的要求。

    放弃可以找到一万个理由,坚持只需一个信念

    在这里插入图片描述

    1.定时任务概念

    01.定时任务作用

    • 自动 完成操作命令
    • 定时备份系统数据信息

    02.定时任务分类

    • 定时任务软件
      • cronie:默认系统自带定时服务crond(crontab)
      • atd:需要安装 at命令(yum -y install at),只运行一次,一次性定时任务
      • anacron非7*24小时运行的服务器

    03.定时任务实现方式

    • 系统定时任务(特殊的几个目录),系统自带的,不灵活

      • 系统定时任务周期:每小时 控制定时任务目
        录:/etc/cron.hourly
      • 系统定时任务周期:每一天 控制定时任务目录:/etc/cron.daily 00:00-23:59
      • 系统定时任务周期:每一周 控制定时任务目录:/etc/cron.weekly 7天
      • 系统定时任务周期:每个月 控制定时任务目录:/etc/cron.monthly 30 28 31
    • 用户定时任务

      • 用户定时任务查看:crontrabl -l(list) ----查看定时任务信息
      • 用户定时任务编辑:crontab -e (edit) ----编辑定时任务信息
      • 定时任务配置文件: /var/spool/cron/root ---- root文件表示root 用户设置的定时任务
    • 常见提示信息

      • no crontab for root:相应用户没有编辑定时任务
      • Do you want to retry the same edit:定时任务编辑错误是否继续
    • 在这里插入图片描述

    2.定时任务实践应用

    01.定时任务 实验环境

    系统版本系统ip地址
    Centos 7.4192.168.10.11
    • 确保crond服务开启

      [root@hbs/tmp]# systemctl status crond
      crond.service - Command Scheduler
         Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
         Active: active (running) since Tue 2021-08-17 15:56:50 CST; 4h 58min ago
       Main PID: 23739 (crond)
         CGroup: /system.slice/crond.service
                 └─23739 /usr/sbin/crond -n
      
      Aug 17 15:56:50 hbs systemd[1]: Started Command ...
      Aug 17 15:56:50 hbs systemd[1]: Starting Command...
      Aug 17 15:56:50 hbs crond[23739]: (CRON) INFO (R...
      Aug 17 15:56:50 hbs crond[23739]: (CRON) INFO (r...
      Aug 17 15:56:50 hbs crond[23739]: (CRON) INFO (@...
      Hint: Some lines were ellipsized, use -l to show in full.
      [root@hbs/tmp]# 
      
    • 相关启动命令

      Centos 6
      service crond start    //启动服务
      service crond stop     //关闭服务
      service crond restart  //重启服务
      service crond reload   //重新载入配置
      service crond status   //查看服务状态 
      
      Centos 7
       systemctl stop crond   //关闭
       systemctl start crond   //开启
       systemctl reload crond   //重新加载
       systemctl restart crond   //重启
       
      

    02.定时任务 配置方法

    2.1定时任务相关文件

    • 定时任务 服务配置文件目录/var/spool/cron
    • 定时任务 运行记录日志文件:/var/log/cron
    • 定时任务 禁止用户运行名单:/etc/cron.deny

    2.2定时任务编写格式

    • 查看编写格式

      [root@hbs/tmp]# cat /etc/crontab 
      SHELL=/bin/bash
      PATH=/sbin:/bin:/usr/sbin:/usr/bin
      MAILTO=root
      
      # For details see man 4 crontabs
      
      # Example of job definition:
      # .---------------- minute (0 - 59)
      # |  .------------- hour (0 - 23)
      # |  |  .---------- day of month (1 - 31)
      # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
      # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
      # |  |  |  |  |
      # *  *  *  *  * user-name  command to be executed
        分  时 日 月 周
      
      [root@hbs/tmp]# 
      
    • 在这里插入图片描述

    • 写法:

      1.用数值表示 时间信息
      00 02 *  *  *  备份文件
      
      2.利用特殊符号表示时间信息
      *     *    *   *    *   备份文件
      /分钟 /小时 /天  /月  /周
      
      =========================================
      PS:定时任务最短执行的周期为 每分钟 
      */5       */ 6     */3      */1    */2
      每隔5分钟  每隔6小时  每隔3日  每隔1月  每隔2周
      
      =========================================
      其它 写法:
      01-05  02  * * *        每2日的01、02、03、04、05 执行一遍
      
      
      指定不连续的时间范围:
      00  14,20  *  *  *  *    每天14点,20点执行一次
      
    • 在这里插入图片描述

    • 补充说明

      00/10  01,03  *  *  *   每天1点和3点的时候 每隔 10分钟,执行一次
      30/10  01,03  *  *  *   每天1点和3点的时候 , 从30分钟开始,每隔 10分钟,执行一次
      
    • 在这里插入图片描述

    2.3 编写步骤

    • 编写步骤

      每天凌晨两点备份 /data目录到 /backup
      
      第一个历程: 写上时间信息
            00 02 * * *
      第二个历程: 写上完成任务的具体命令
            cp -a /data /backup
      第三个历程: 编写定时任务
            crontab -e 
            00 02 * * *  cp -a /data /backup
            
      ======================================
        [root@hbs~]#crontab -e 
       00 02 * * *  cp -a /data /backup	 
      
      

    2.4定时任务编写注意事项:(规范)

    • 编写定时任务要有注释说明

    • 编写定时任务路径信息尽量使用绝对路径

    • 编写定时任务命令需要采用绝对路径执行 /usr/sbin/useradd

      命令执行成功条件:
      	   useradd  ---> $PATH ---> /sbin/useradd ---> 命令执行成功
      	   定时任务执行时,识别的PATH信息只有: /usr/bin:/bin
      	   useradd命令--->usr/sbin/useradd
      
      所以,编写要写绝对路径
      useradd命令--->usr/sbin/useradd
      
    • 编写定时任务时,可以将输出到屏幕上的信息保存到黑洞中,避免占用磁盘空间

      sh test.sh &>/dev/null
      
    • 编写定时任务, 尽量不要产生屏幕输出信息

      tar zcvf /backup/data.tar.gz  /data    有信息输出
      
      tar zcf /backup/data.tar.gz  ./data    没有信息输出
      
    • 当需要多个命令完成一个定时任务需求时,可以利用脚本编写定时

      vim backup.sh 
      	   cp -a /data /backup	
      	   tar zcvf /backup/data.tar.gz  /data
      	   
      	   crontab -e 
      	   # xxxxx
      	   * * * * *  /bin/sh /server/scripts/backup.sh &>/dev/null
      
      
    • 在这里插入图片描述

    总结

    • 对定时任务排查的方法

      1.检查是否有定时任务配置文件
      
      2.检查定时任务日志文件
      [root@hbs~]# tail -f /var/log/cron
      Aug 17 21:27:49 hbs crontab[26501]: PAM pam_end: NULL pam handle passed
      Aug 17 21:39:27 hbs crontab[26577]: (root) END EDIT (root)
      Aug 17 21:39:27 hbs crontab[26577]: PAM pam_end: NULL pam handle passed
      Aug 17 21:40:58 hbs  crontab[26595]: (hbs) END EDIT (hbs)
      Aug 17 21:41:01 hbs  CROND[26598]: (hbs) CMD (systemctl status crond)
      执行时间        主机名 编辑定时任务    以什么用户编辑或执行定时任务/干了什么事情  执行定时任务
      
      
    • 定时任务还有atd 定时任务

      at命令是一次性定时计划任务,执行完一个任务后不再执行此任务了。
      
       at -f /tmp/date now +1 minutes   #设置1分钟后执行/tmp/date文件中的内容
       
       
       明天17点钟,输出时间到指定文件内
       [root@hbs~]# echo 'love you' >/dev/null 
      [root@hbs~]#  at 17:00 tomorrow         
      at> echo 'love you' >/dev/null 
      at> <EOT>
      job 8 at Thu Aug 19 17:00:00 2021
      Can't open /var/run/atd.pid to signal atd. No atd running?
      [root@hbs~]# 
      
      删除已经设置的任务
      atq : 查看定时任务
      atrm 8  :删除定时任务
      
    • 在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 分布式定时任务开源方案

    千次阅读 2022-03-25 23:35:29
    整理了常用的几种分布式定时任务开源方案的优缺点对比。

    方案对比
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eITo4Sm1-1648222509512)(定时任务.assets/8b0ef8fc44b2020f2e477917e6a8fa79.png)]

     

    1、quartz

       quartz的集群方案是使用数据库来实现的。通过在数据库中配置定时器信息, 以数据库悲观锁的方式达到同一个任务始终只有一个节点在运行。

     「项目地址:https://github.com/quartz-scheduler/quartz 」

     「go的开源实现:https://github.com/reugn/go-quartz 」

     

    1.1 架构

      集群架构如下:

    在这里插入图片描述

      上图三个节点在数据库中都拥有同一份Job定义,如果某一个节点失效,那么Job会在其他节点上执行。

       由于三个节点上的Job执行代码是一样的,那么怎么保证只有在一台机器上触发呢?答案是使用了数据库锁。

      在quartz的集群解决方案里有张表scheduler_locks,quartz采用了「悲观锁」的方式对triggers表进行行加锁,以保证任务同步的正确性。一旦某一个节点上面的线程获取了该锁,那么这个Job就会在这台机器上被执行,同时这个锁就会被这台机器占用。同时另外一台机器也会想要触发这个任务,但是锁已经被占用了,就只能等待,直到这个锁被释放。之后会看trigger状态,如果已经被执行了,则不会执行了。

       简单地说,quartz的分布式调度策略是以数据库为边界资源的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性。同时多个节点的异步运行保证了服务的可靠。但这种策略有自己的局限性:集群特性对于高CPU使用率的任务效果很好,但是对于大量的短任务,各个节点都会抢占数据库锁,这样就出现大量的线程等待资源。这种情况随着节点的增加会越来越严重。

     

    1.2 优缺点

    优点:

    1. 保证节点高可用 (HA), 如果某一个几点挂了, 其他节点可以顶上

    缺点:

    1. 同一个任务只能有一个节点运行,其他节点将不执行任务,性能低,资源浪费
    2. 当碰到大量短任务时,各个节点频繁的竞争数据库锁,节点越多这种情况越严重。性能会很低下
    3. quartz 的分布式仅解决了集群高可用的问题,并没有解决任务分片的问题,不能实现水平扩展

     

    2、elastic-job

       elastic-job 是由当当网基于quartz 二次开发之后的分布式调度解决方案 , 由两个相对独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成 。

       Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。一般我们只要使用Elastic-Job-Lite就好。

    「项目地址:https://github.com/dangdangdotcom/elastic-job 」

     

    2.1 架构

       Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。

       Elastic-Job-Cloud使用Mesos + Docker(TBD)的解决方案,额外提供资源治理、应用分发以及进程隔离等服务

     

    2.2 优缺点

    优点:

    1. 基于quartz 定时任务框架为基础的,因此具备quartz的大部分功能

    2. 使用zookeeper做协调,调度中心,更加轻量级

    3. Elastic-Job-Lite并没有宿主程序,而是基于部署作业框架的程序在到达相应时间点时各自触发调度。它的开发也比较简单,引用Jar包实现一些方法即可,最后编译成Jar包运行。

    4. Elastic-Job-Lite的分布式部署全靠ZooKeeper来同步状态和原数据。实现高可用的任务只需将分片总数设置为1,并把开发的Jar包部署于多个服务器上执行,任务将会以1主N从的方式执行。一旦本次执行任务的服务器崩溃,其他执行任务的服务器将会在下次作业启动时选择一个替补执行。如果开启了失效转移,那么功能效果更好,可以保证在本次作业执行时崩溃,备机之一立即启动替补执行。

    5. Elastic-Job-Lite的任务分片也是通过ZooKeeper来实现,Elastic-Job并不直接提供数据处理的功能,框架只会将分片项分配至各个运行中的作业服务器,开发者需要自行处理分片项与真实数据的对应关系。框架也预置了一些分片策略:平均分配算法策略,作业名哈希值奇偶数算法策略,轮转分片策略。同时也提供了自定义分片策略的接口。

    6. Elastic-Job-Lite还提供了一个任务监控和管理界面:Elastic-Job-Lite-Console。它和Elastic-Job-Lite是两个完全不关联的应用程序,使用ZooKeeper来交换数据,管理人员可以通过这个界面查看、监控和管理Elastic-Job-Lite的任务,必要的时候还能手动触发任务。

      关注的是数据,增加了弹性扩容和数据分片的思路,以便于更大限度的利用分布式服务器的资源。但是学习成本相对高些,推荐在“数据量庞大,且部署服务器数量较多”时使用。

       elastic-job结合了quartz非常优秀的时间调度功能,并且利用ZooKeeper实现了灵活的分片策略。除此之外,还加入了大量实用的监控和管理功能,以及其开源社区活跃、文档齐全、代码优雅等优点,是分布式任务调度框架的推荐选择。

    缺点:

    1. 引入的依赖较多,会增加系统的复杂度。

     

    3、xxl-job

       xxl-job是由个人开源的一个轻量级分布式任务调度框架 ,主要分为调度中心和执行器两部分,调度中心在启动初始化的时候,会默认生成执行器的RPC代理。

       对象(http协议调用), 执行器项目启动之后, 调度中心在触发定时器之后通过jobHandle 来调用执行器项目里面的代码,核心功能和elastic-job差不多,同时技术文档比较完善。

    「项目地址: https://github.com/xuxueli/xxl-job 」

     

    3.1 架构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dIMa4nXC-1648222509514)(定时任务.assets/3b4e00f1bfa40e9910b368880b5df0e8.png)]

      调度中心通过获取DB锁来保证集群中执行任务的唯一性。

     

    3.2 优缺点

    优点:

    1. 文档比较详细,xxl-job分为调度中心(中心式)和执行器(分布式),调度中心基于集群Quartz实现并支持集群部署,可保证调度中心HA;任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA,其中调度中心集群基于DB,而其他两个框架用zookeeper崃实现分布式锁。
    2. 侧重的业务实现的简单和管理的方便,学习成本简单,失败策略和路由策略丰富。推荐使用在“用户基数相对少,服务器数量在一定范围内”的情景下使用,版本更新较快也是其一大亮点,支持子任务,DAG任务和依赖任务已经列入TODOLIST,暂时不支持秒任务,具体支持如下:
    3. 支持多种语言作业,语言无关(Java/Go/C++/PHP/Python/Ruby/shell)
    4. 分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;
    5. 动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
    6. 支持作业高可用
    7. 弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;
    8. 故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
    9. 事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。
    10. 任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔;
    11. 容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用;
    12. 任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试;

     
    缺点:

    1. 短时任务多时,数据库的锁竞争激烈,影响性能

     

    4、Saturn

      Saturn是唯品会在github开源的一款分布式任务调度产品。它是基于当当elastic-job 1.0版本来开发的,其上完善了一些功能和添加了一些新的feature。

    「 项目地址:https://github.com/vipshop/Saturn 」

     

    4.1 架构

    Saturn包括两大部分,Saturn ConsoleSaturn Executor

    • Saturn Console是一个GUI,用于作业/Executor管理,统计报表展现,系统配置等功能。它同时也是整个调度系统的大脑:将作业任务分配到各Executor。

      为了实现Console的高可用性,我们都希望Console有多台服务器所组成。我们只需要在多台不同的服务器的环境变量中指定相同的VIP_SATURN_CONSOLE_CLUSTER即可,至于VIP_SATURN_CONSOLE_CLUSTER的值,由你自行指定,只是一个集群标识而已。

    • Saturn Executor是执行任务的Worker:按照作业配置的要求去执行部署于Executor所在容器或物理机当中的作业脚本和代码。

     

    4.2 优缺点

    优点:

    1. 支持基于事件和时间触发
    2. 支持多种语言作业,语言无关(Java/Go/C++/PHP/Python/Ruby/shell)
    3. 支持秒级调度
    4. 支持作业分片并行执行
    5. 支持依赖作业串行执行
    6. 支持作业高可用和智能负载均衡
    7. 支持异常检测和自动失败转移
    8. 支持异地容灾
    9. 支持多个集群部署
    10. 支持跨机房区域部署
    11. 支持弹性动态扩容
    12. 支持优先级和权重设置
    13. 支持docker容器,容器化友好
    14. 支持cron时间表达式
    15. 支持多个时间段暂停执行控制
    16. 支持超时告警和超时强杀控制
    17. 支持灰度发布
    18. 支持异常、超时和无法高可用作业监控告警和简易的故障排除
    19. 支持失败率最高、最活跃和负荷最重的各域各节点TOP10的作业统计
    20. 支持简单的DAG任务和依赖任务
    21. 可视化管理

     

    缺点:

    1. 技术文档较少 , 该框架是2016年由唯品会的研发团队基于elastic-job开发而来的

     

    5、antares

    5.1 架构

    在这里插入图片描述

    5.2 优缺点

    优点:

    1. 一个任务仅会被服务器集群中的某个节点调度,调度机制基于成熟的 quartz
    2. 并行执行 , 用户可通过对任务预分片,有效提升任务执行效率
    3. 失效转移
    4. 弹性扩容,在任务运行时,可以动态的加机器
    5. 友好的管理控制台

     
    缺点:

    1. 不能动态的添加任务,仅能在控制台对任务进行触发,暂停,删除等操作
    2. 文档不多,开源社区不够活跃

     

    6、opencron

       opencron是 一个功能完善真正通用的linux定时任务调度定系统,满足多种场景下各种复杂的定时任务调度,同时集成了linux实时监控,webssh,提供一个方便管理定时任务的平台。

     

    6.1 优缺点

    优点:

    • 自动化管理任务,提供可操作的web图形化管理
    • 时间规则支持quartz和crontab,更强大更灵活
    • 任务的运行状态实时查看
    • 支持任务kill(包括由当前任务调起的其他子任务链,彻底kill)
    • 支持重新执行正在运行的任务
    • 出错后实时通知给任务人(超过重跑次数自动发送邮件,短信)
    • 支持任务超时设置,一旦超过预定运行时长自动kill,任务结束,防止僵尸任务
    • 支持流程任务(多台机器上协同完成一个大的任务,按任务分配的顺序依次执行每台机器上的任务)
    • 记录任务的运行日志,非常方便查看
    • 多用户多角色
    • 提供服务器的性能实时监控

     

    缺点:

    1. 仅支持 kill任务,现场执行,查询任务运行状态等,主要功能是着重于任务的修改和查询上。
    2. 不能动态的添加任务以及任务分片。

     
     
    参考链接:
    https://www.cnblogs.com/haoxinyue/p/6886196.html
    https://blog.csdn.net/weixin_39605894/article/details/110982518
    https://www.cnblogs.com/rainswinds/p/10930495.html
    https://blog.csdn.net/taosir_zhang/article/details/50728362
     
    如有不对,烦请指出,感谢~

    展开全文
  • 定时任务,松哥之前写过多篇文章和大家介绍,上次还自己 DIY 了一个可以动态编辑的定时任务,还录了一个配套视频: 相关的资料链接戳这里: Spring 定时任务玩出花! 手把手教你定制可编辑的定时任务! 开发可配置...
  • Java实现定时任务

    万次阅读 2022-04-06 23:11:54
    这种方式的定时任务主要用到两个类,Timer 和 TimerTask,使用起来比较简单。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。 TimerTask是一个抽象类,new的时候实现自己的 run 方法,然后将其丢给 Timer 去...
  • 先说一下个人的这个使用背景:项目中需要引入定时任务,框架是springcloud分布式系统然后调研之后决定引入Quartz,他需要基于数据库特定的表来存储定时任务相关的数据等,普通的定时任务比如:日终定时批量进行某些...
  • Spring+Quartz 从数据库中获取定时任务和定时时间,动态实现对定时任务的增删改查,部署到tomcat即可看到定时任务执行效果。本人亲测,可用!
  • Java 定时任务-最简单的3种实现方法

    千次阅读 多人点赞 2022-03-07 16:01:27
    一、Timer ...Timer是JAVA自带的定时任务类,实现如下: publicclassMyTimerTask{ publicstaticvoidmain(String[]args){ //定义一个任务 TimerTasktimerTask=newTimerTask(){ @Override publicv...
  • 分布式定时任务的解决方案

    千次阅读 2021-07-07 22:32:30
    把分散的,可靠性差的计划任务纳入统一的平台,并实现集群管理调度和分布式部署的一种定时任务的管理方式,就叫做分布式定时任务。 它有两层含义: 它是运行在分布式集群环境下的调度任务,同⼀个定时任务程序部署...
  • SpringBoot 如何执行定时任务

    千次阅读 2021-03-29 10:10:56
    SpringBoot 如何执行定时任务 工作中有需要应用到定时任务的场景,一天一次,一周一次,一月一次,一年一次,做日报,周报,月报,年报的统计,以及信息提醒,等,spring boot 提供了一个两种方式实现定时任务。 ...
  • Java如何实现定时任务

    千次阅读 2022-03-26 21:01:32
    看完这篇文章你会了解到什么是定时任务,以及为什么austin项目要引入分布式定时任务框架,可以把代码下载下来看到我是怎么使用xxl-job的。 01、如何简单实现定时功能? 我是看视频入门Java的,那时候学Java基础API的...
  • 最近,有个项目有需要用到定时任务,所以做了一个动态管理定时任务的模块。本文将从项目背景、需求、选型、思路、具体实现等方面展开介绍。 背景:有个支付类的项目,中间会产生一些中间态的订单,需要有个定时...
  • Linux 定时任务详解

    万次阅读 多人点赞 2021-10-11 20:59:09
    今天继续给大家介绍Linux基础知识,本文主要内容是Linux定时任务。 一、Linux定时任务简介 计划任务是需要在指定时间执行的任务或者是周期性执行的任务,比如凌晨3点重启设备,每周对日志文件备份等。Linux系统会...
  • Java中定时任务的6种实现方式,你知道几种?

    万次阅读 多人点赞 2021-08-05 07:36:11
    几乎在所有的项目中,定时任务的使用都是不可或缺的,如果使用不当甚至会造成资损。还记得多年前在做金融系统时,出款业务是通过定时任务对外打款,当时由于银行接口处理能力有限,外加定时任务使用不当,导致发出...
  • 点击关注公众号,利用碎片时间学习序言SpringBoot创建定时任务,目前主要有以下三种实现方式:基于注解(@Scheduled): 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的...
  • 定时任务的实现

    千次阅读 2022-01-26 17:05:42
    定时任务,cron表达式,ScheduledThreadPoolExecutor,quartz
  • 定时执行专家》是一款制作精良、功能全面、使用简单的专业定时执行工具软件。支持 18 种任务类型,11 种任务触发方式(包含 Cron方式),触发精度达到“秒”级。软件无需安装,无使用时间限制,欢迎下载使用。软件...
  • 在 springBoot 项目中,要使用定时任务变得十分容易,我们只需使用@EnableScheduling 开启定时任务支持,再配合 @Scheduled(cron = "cron表达式"),即可简单的集成定时任务功能,简单方便的同时,此种方式却也存在着...
  • Springboot动态实现定时任务

    千次阅读 2022-02-23 14:32:19
    springboot实现动态的定时任务
  • 前面的章节,用户通过绑定手机号的注册为会员,并可以补充完个人信息,比如姓名、生日等信息,拿到用户的生日信息之后,就可以通过会员生日信息进行营销,此处就涉及到定时任务执行营销信息推送的问题。本篇就带你...
  • Python 实现定时任务的八种方案

    千次阅读 2022-02-18 10:26:14
    接下里整理的是常见的Python定时任务的实现方式。 目录 利用while True: + sleep()实现定时任务 使用Timeloop库运行定时任务 利用threading.Timer实现定时任务 利用内置模块sched实现定时任务 利用调度...
  • Django定时任务四种实现方法总结

    千次阅读 2022-03-01 18:31:16
    Django定时任务三种实现方法总结一、使用django-crontab插件来实现定时任务二、使用django-apscheduler插件实现定时任务二、附件部分(django-apscheduler功能详解)三、使用Celery插件实现定时任务四、自建代码实现...
  • 【SpringBoot】25、SpringBoot中使用Quartz管理定时任务

    万次阅读 多人点赞 2020-07-21 15:55:47
    定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任务的...
  • maven工程-基于springboot定时任务

    千次下载 热门讨论 2016-07-21 18:18:01
    基于springboot的定时任务实现
  • 文章目录一、功能说明二、快速使用三、实现原理1、动态管理实现(1) 配置管理介绍(2) 使用后处理器拦截SpringBoot原本的定时任务(3) 使用ApplicationRunner初始化自定义的定时任务运行器(4) 进行动态管理2、增强接口...
  • 创建Oracle定时任务

    千次阅读 2022-03-18 11:19:06
    PLSQL 创建Oracle定时任务 用语句创建 1、创建任务执行的存储过程,如名称为testJob,向测试表中插入数据,如文章开头,此处省略。 2、创建一个 定时任务 job declare job number; BEGIN DBMS_JOB.SUBMIT( ...
  • cron定时任务详解

    千次阅读 2021-04-15 13:38:03
    crond是什么? crond 和crontab是不可分割的。crontab是一个命令,常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。...linux定时任务分为两种 1)系统自身轮训的任务,比如定时(5天或者
  • 定时任务的10种写法,长见识了

    千次阅读 2021-12-21 16:00:28
    最近有几个读者私信给我,问我他们的业务场景,要用什么样的定时任务。确实,在不用的业务场景下要用不同的定时任务,其实我们的选择还是挺多的。我今天给大家总结10种非常实用的定时任务,总有一种是适合你的。 一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 406,472
精华内容 162,588
关键字:

定时任务