负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块。
负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;
接收“调度中心”的执行请求、终止请求和日志请求等。
线程池配置:2核心线程数,最大线程数10,任务队列2000,活跃时间30s,执行+日志的拒绝策略。
快线程池配置:10核心线程数,最大线程数至少200,任务队列1000
慢线程池配置:10核心线程数,最大线程数至少100,任务队列2000
job超时次数超过500ms为超时,一分钟内任务超时次数超过10次(不包含10),运行触发任务有快线程池fastTriggerPool降级为慢线程池slowTriggerPool
为什么要控制? 因为触发中心是集群部署,每个实例都会执行触发任务。需要控制在某一时刻只有一个实例在触发任务。
ringData, Map<秒数, List>
//存数
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
ringItemData.add(jobId);
//取数
int nowSecond = Calendar.getInstance().get(Calendar.SECOND);
for (int i = 0; i < 2; i++) {
List<Integer> tmpData = ringData.remove( (nowSecond+60-i)%60 );
if (tmpData != null) {
ringItemData.addAll(tmpData);
}
}
job超时统计
long minTim_now = System.currentTimeMillis()/60000;
if (minTim != minTim_now) {
minTim = minTim_now;
jobTimeoutCountMap.clear();
}
预读数量计算:(快线程大小 + 慢线程池大小) * 20 默认:(200 + 100)* 20 = 6000
预读时间:5秒。 运行中的Job
下一秒开始 TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
获取当前秒和过去1秒的任务。ringData删除掉已经触发的任务。
1、快慢线程池设计,降级处理,防止正常触发的任务被慢job阻塞。
2、ConcurrentMap存储超时次数,在多线程场景下的使用。
3、job超时统计数据保存时效逻辑
long minTim_now = System.currentTimeMillis()/60000;
if (minTim != minTim_now) {
minTim = minTim_now;
jobTimeoutCountMap.clear();
}
注册中心回调线程池callbackThreadPool:2核心线程数,最大线程数20,任务队列3000,活跃时间30s,执行+日志的拒绝策
job处理成功处理,主要是触发子任务,多个子任务配置用逗号分割,逐个触发子任务。
更新job日志信息,增加触发子任务的信息,日志截取避免超过text类型大小(64kb)。
支持 zh_CN:中文简体, zh_TC:中文繁体, en:英文
默认是zh_CN. 通过配置xxl.job.i18n可以设置。
根据不同的语言选择,加载不同的国际化文件
message_zh_CN.properties,
message_zh_TC.properties,
message_en.properties
将系统内的语言修改成对应的语言。
按天统计,统计近3天的数据。1分钟更新log-report表
log日志清理逻辑。 job-log最少保存7天。一天清理一次log。
InheritableThreadLocal主要用于子线程创建时,需要自动继承父线程的ThreadLocal变量,方便必要信息的进一步传递。
在维持Jobcontext的时候就使用了InheritableThreadLocal,方便子线程使用。
take方法会一直阻塞,poll允许继续执行。在执行job时候就使用的poll,以便于统计空转的次数,超过30次,kill掉线程,以释放无用的线程占用内存空间。
对齐配合配合时间轮逻辑
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);