xxl-job原理(版本2.3.1)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
一、xxl-job架构图
1、调度中心
负责管理调度信息按照调度配置发出调度请求自身不承担业务代码。调度系统与任务解耦提高了系统可用性和稳定性同时调度系统性能不再受限于任务模块。
2、执行器
负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作开发和维护更加简单和高效
接收“调度中心”的执行请求、终止请求和日志请求等。
二、执行器注册流程
1、调度中心注册注册/删除异步处理
线程池配置2核心线程数最大线程数10任务队列2000活跃时间30s执行+日志的拒绝策略。
2、注册数据处理流程
三、调度中心触发任务
1、任务触发快慢线程池设计
快线程池配置10核心线程数最大线程数至少200任务队列1000
慢线程池配置10核心线程数最大线程数至少100任务队列2000
2、job降级逻辑
job超时次数超过500ms为超时一分钟内任务超时次数超过10次不包含10运行触发任务有快线程池fastTriggerPool降级为慢线程池slowTriggerPool
3、触发启动加排他锁
为什么要控制 因为触发中心是集群部署每个实例都会执行触发任务。需要控制在某一时刻只有一个实例在触发任务。
4、时间轮
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();
}
5、触发job预读5s数据
预读数量计算快线程大小 + 慢线程池大小 * 20 默认200 + 100* 20 = 6000
预读时间5秒。 运行中的Job
6、ringData读取逻辑
下一秒开始 TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
获取当前秒和过去1秒的任务。ringData删除掉已经触发的任务。
7、添加触发任务流程
1、快慢线程池设计降级处理防止正常触发的任务被慢job阻塞。
2、ConcurrentMap存储超时次数在多线程场景下的使用。
3、job超时统计数据保存时效逻辑
long minTim_now = System.currentTimeMillis()/60000;
if (minTim != minTim_now) {
minTim = minTim_now;
jobTimeoutCountMap.clear();
}
8、调度中心触发job-路由策略
四、任务执行
五、任务回调
注册中心回调线程池callbackThreadPool2核心线程数最大线程数20任务队列3000活跃时间30s执行+日志的拒绝策
job处理成功处理主要是触发子任务多个子任务配置用逗号分割逐个触发子任务。
更新job日志信息增加触发子任务的信息日志截取避免超过text类型大小64kb。
失败job处理流程monitorThread
六、设计的细节点。
1、国际化设计
支持 zh_CN中文简体, zh_TC中文繁体, en英文
默认是zh_CN. 通过配置xxl.job.i18n可以设置。
根据不同的语言选择加载不同的国际化文件
message_zh_CN.properties,
message_zh_TC.properties,
message_en.properties
将系统内的语言修改成对应的语言。
2、job调用统计
按天统计统计近3天的数据。1分钟更新log-report表
log日志清理逻辑。 job-log最少保存7天。一天清理一次log。
3、InheritableThreadLocal的使用
InheritableThreadLocal主要用于子线程创建时需要自动继承父线程的ThreadLocal变量方便必要信息的进一步传递。
在维持Jobcontext的时候就使用了InheritableThreadLocal方便子线程使用。
4、LinkedBlockingQueue take和poll的巧妙应用
take方法会一直阻塞poll允许继续执行。在执行job时候就使用的poll以便于统计空转的次数超过30次kill掉线程以释放无用的线程占用内存空间。