之前,我们研究了执行1次的任务,但是实际生产环境中,我们可能需要很多个定时调度的需求,
所以,接下来,我们来研究定时调度的原理!
========================================================================
点开这个按钮后,出现新的界面如下:
填写自己的数值后,提交Schedule按钮后,观察URL
对应的URL===>
.POST /schedule HTTP/1.1
看来需要去查阅一个新的URL Servlet
root.addServlet(new ServletHolder(new ScheduleServlet()), "/schedule");
========================================================================================
jdb azkaban.webapp.AzkabanWebServer -conf /root/azkb/azkaban_3.
0
.0_debug/conf
stop in azkaban.webapp.servlet.ScheduleServlet.doPost
stop in azkaban.webapp.servlet.ScheduleServlet.ajaxScheduleFlow
stop in azkaban.scheduler.ScheduleManager.scheduleFlow
run
========================================================================================
最后执行的是ExecutorServlet的下面的方法
@Override
protected void handlePost(HttpServletRequest req, HttpServletResponse resp,
Session session) throws ServletException, IOException {
//看到这里了
if (hasParam(req, "ajax")) {
handleAJAXAction(req, resp, session);
}
}
经过一番参数解析后,后面会有这样的一段代码
Schedule schedule = scheduleManager.scheduleFlow(-1, projectId, projectName, flowName, "ready",
firstSchedTime.getMillis(), firstSchedTime.getZone(), thePeriod, DateTime.now().getMillis(),
firstSchedTime.getMillis(), firstSchedTime.getMillis(), user.getUserId(), flowOptions, slaOptions);
logger.info("User '" + user.getUserId() + "' has scheduled " + "[" + projectName + flowName + " (" + projectId
+ ")" + "].");
这个倒是需要仔细研究下~
========================================================================================
正如单次运行是放入一个queue中一样,对于循环执行的任务,放入一个线程的队列里
public class TriggerManager extends EventHandler implements
里面有一个线程
private final TriggerScannerThread runnerThread;
任务是如何插入到这个线程的呢?
原因就在于,之前有个函数
public void insertTrigger(Trigger t) throws TriggerManagerException {
synchronized (syncObj) {
try {
triggerLoader.addTrigger(t);
} catch (TriggerLoaderException e) {
throw new TriggerManagerException(e);
}
runnerThread.addTrigger(t);//看这里
triggerIdMap.put(t.getTriggerId(), t);
}
}
public void addTrigger(Trigger t) {
synchronized (syncObj) {
t.updateNextCheckTime();
triggers.add(t);
}
}
private class TriggerScannerThread extends Thread {
private BlockingQueue<Trigger> triggers;
这样,一个调度任务就插入到了一个BlockingQueue,
当然,如果有兴趣的话,还可以看这个变量的初始化部分:
public TriggerScannerThread(long scannerInterval) {
triggers = new PriorityBlockingQueue<Trigger>(1, new TriggerComparator());
justFinishedFlows = new ConcurrentHashMap<Integer, ExecutableFlow>();
this.setName("TriggerRunnerManager-Trigger-Scanner-Thread");
this.scannerInterval = scannerInterval;
}
原来是一个PriorityBlockingQueue,这样排序都不用自己做了,很方便!
------------------
先看看这个线程什么上下文初始化的?
下文再说!