新任务管理系统YYSchedule-细节-队列优先级实现


一、介绍

在本调度平台中,将以job为单位进行优先级设定,为什么要进行优先级设定呢?

举个例子: 一小时前用户A下发了100个病毒检测应用程序的任务,而现在突然想尽快检测新拥有的50个应用,但之前的100个检测任务并未完全执行完,如果不设置优先级,则新下发的50个任务进行排队,等待上一次100个应用程序检测完成后再进行检测。

如果设置了优先级,则每个节点会获取优先级高的任务,再提交给引擎进行检测,这样就实现了所谓“插队”的功能。

二、新调度平台优先级队列设计思路:

任务下发的队列图如下,我们对其中的两条priorityTaskQueue以及distributeTaskQueue进行了优先级化。需要注意的是,两条队列实现优先级的方法并不相同,前者使用的是java自带的“PriorityBlockingQueue”,而后者使用的是activemq的优先级方法。在下文我们会分别对两种方法的实现进行讲解。

任务下发机制-队列图

三、实现

1、优先级标识

在YYSchedule中,我们自定义了任务类Task,在这个类中,有一个参数JobPriority,这个参数就是任务的优先级。

其中JobPriority是通过thrift生成,核心代码如下:

public enum JobPriority implements org.apache.thrift.TEnum {
  HIGHER(9),
  HIGH(6),
  MEDIUM(4),
  LOW(2),
  LOWER(0);
}

之所以设置0 2 4 6 9这五个值,是为了和JMS的优先级对应。

2、priorityTaskQueue的优先级实现

priorityTaskQueue使用的是java自带的“PriorityBlockingQueue”,其存储的是自定义类Task:

private PriorityBlockingQueue<Task> priorityTaskQueue = new PriorityBlockingQueue<Task>();

使用PriorityBlockingQueue有一个前提:PriorityBlockingQueue里面存储的对象必须是实现Comparable接口。队列通过这个接口的compare方法确定对象的priority。

规则是:当前和其他对象比较,如果compare方法返回负数,那么在队列里面的优先级就比较高。也就是说,值越小优先级越大,注意这个与平时的习惯是相反的。

因此我们在Task.java这个javaBean中实现了Comparable,并实现了compareTo方法,代码如下:

@Override
	public int compareTo(Task task) {
		if (task != null && task.getTaskId() != 0L && task.getTaskId().equals(taskId)) {
			return 0;
		}
		if (taskPriority.getValue() == task.getTaskPriority().getValue()) {
			return -(Long.valueOf(loadedTime).compareTo(task.getLoadedTime()));
		}
		return -(Integer.valueOf(taskPriority.getValue()).compareTo(task.getTaskPriority().getValue()));
	}

通过这种方法,我们便可以实现priorityTaskQueue的优先级。

3、distributeTaskQueue的优先级实现(activemq)

在spring集成activemq时,jmsTemplate提供了setPriority方法,最高为9,最低为0,数值越高优先级越高。

但需要注意的是,若想使用优先级功能,必须先设置ExplicitQosEnabled为true,也就是jmsTemplate.setExplicitQosEnabled(true);

具体实现代码请见我的另一篇博客:《调度平台YYSchedule-细节-activemq的使用》

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/290386.html

(0)
上一篇 2022年10月2日
下一篇 2022年10月2日

相关推荐

发表回复

登录后才能评论