分布式定时任务

什么是定时任务

       定时任务是指基于给定的时间点、给定的时间间隔或者给定的执行次数自动执行一项或多项任务。

常用的定时任务如下。
1.crontab命令
直接使用linux系统自带的crontab程序进行定时任务控制。

2.JDK Timer
java.util.Timer定时器为单线程,定时调度所拥有的TimeTask任务。

public class HelloTimerTask extends TimerTask{
	@Override
	public void run() {
		System.out.println(new Date());
	}
}
public class HelloTimer {
	public static void main(String[] args) {
		Timer timer = new Timer();
		System.out.println(new Date());
		timer.schedule(new HelloTimerTask(), 1000, 2000);
	}
}

Timer类缺陷如下:

  • 时间延迟不准确。由于是单线程执行,如果某个任务执行时间过长,可能导致后续任务时间延迟。
  • 异常终止。如果任务抛出未捕获的异常,会导致Timer线程终止,所有任务终止。
  • 执行周期任务时依赖系统时间。当系统时间发生变化,会导致执行上的变化。

3.ScheduledExecutor

public class HelloTask implements Runnable{
	@Override
	public void run() {
		System.out.println(new Date());
	}
}
public class HelloScheduledExecutor {
	public static void main(String[] args) {
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
		executor.schedule(new HelloTask(),1,TimeUnit.SECONDS);
		executor.scheduleAtFixedRate(new HelloTask(), 1, 2, TimeUnit.SECONDS);
		executor.scheduleWithFixedDelay(new HelloTask(), 1, 2, TimeUnit.SECONDS);
	}
}

ScheduledThreadPool内部使用线程池实现,各个任务之间并发执行,互相隔离

4.Spring Scheduler

public class HelloTask {
	public void doTask() {
		SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss.SSS");
		System.out.println("hello world " + sdf.format(new Date()));
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}


	
	
	
		
	

ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");

5.Quartz

传统定时任务存在的问题

       业务发展初期,批量任务可以部署在单一服务器上,上文的定时任务实现方式均可以实现,但是随着业务增多,全部作业调度任务放在一台机器上执行存在明显缺陷:单点风险和资源分布不均。

如何将任务分散到不同机器上执行
1.通过配置参数分散运行,例如在不同机器的properties文件中配置不同的任务;
2.通过分布式锁互斥执行,详见https://blog.csdn.net/penguinhao/article/details/83515024

分布式定时任务的两种处理方式

  • 抢占式:谁先获得资源谁执行,这种模式无法将单个任务的数据交给其他节点协同处理,一般用于处理数据量较小、任务较多的场景。
  • 协同式:可以将单个任务处理的数据均分到多个JVM中处理,提高数据的并行处理能力。

开源框架

Quartz的分布式模式
TBSchedule
Elastic-Job

你可能感兴趣的:(分布式定时任务)