就是一个
public abstract class TimerTask implements Runnable {
Runnable的运行,和一个延时时间。
延迟delay毫秒后执行,
主要还是关心下
DeliverDelayedMessageTimerTask(level, offset)
这个类干了什么
org.apache.rocketmq.store.schedule.ScheduleMessageService.DeliverDelayedMessageTimerTask#DeliverDelayedMessageTimerTask
这个类差不多200行,占了ScheduleMessageService的一半。。看来是很重要了,不过也只是个实现Runnable接口的类而已
class DeliverDelayedMessageTimerTask extends TimerTask {
private final int delayLevel;
private final long offset;
public DeliverDelayedMessageTimerTask(int delayLevel, long offset) {
this.delayLevel = delayLevel;
this.offset = offset;
}
构造方法很简单,就不细看了
看下run()方法:
@Override
public void run() {
try {
if (isStarted()) {
this.executeOnTimeup();
}
} catch (Exception e) {
// XXX: warn and notify me
log.error("ScheduleMessageService, executeOnTimeup exception", e);
ScheduleMessageService.this.timer.schedule(new DeliverDelayedMessageTimerTask(
this.delayLevel, this.offset), DELAY_FOR_A_PERIOD);
}
}
看到这儿,我似乎明白了前面那个循环执行。前面那个循环设置定时任务,其实是找到一个延时等级,一个进度offset,然后从此处开始,一直循环发延时消息,也就是比如我的延时等级是3,那么实际发出的延时消息是:1,2,3
为什么要发这么多条呢,到了这儿,明白了,
if (isStarted()) {
this.executeOnTimeup();
}
看这行,如果已经启动了,那么会升级时间executeOnTimeup
但是为什么要采用升级时间的方式,而不直接在发任务的时候就把时间计算好呢,这个还不知道。
try {
if (isStarted()) {
this.executeOnTimeup();
}
} catch (Exception e) {
// XXX: warn and notify me
log.error("ScheduleMessageService, executeOnTimeup exception", e);
ScheduleMessageService.this.timer.schedule(new DeliverDelayedMessageTimerTask(
this.delayLevel, this.offset), DELAY_FOR_A_PERIOD);
}
// 这行代码是在上面声明的
private static final long DELAY_FOR_A_PERIOD = 10000L;
如果执行出现异常,会把当前消息重新设置定时任务发送,时间为10s之后,相当于一个重试机制了