43 changed files with 3000 additions and 106 deletions
@ -0,0 +1,53 @@ |
|||||
|
<template> |
||||
|
<q-tr> |
||||
|
<q-td v-for="(col, index) in cols" :key="col.name" :style="{ 'padding-left': index == 0 ? '2px' : '7px' }"> |
||||
|
<div class="flex flex-nowrap items-center"> |
||||
|
<template v-if="index == 0"> |
||||
|
<!--层级占位符--> |
||||
|
<span :style="`width:${27 * props.level}px;`"></span> |
||||
|
<!--展开按钮--> |
||||
|
<q-btn |
||||
|
v-if="data.children && data.children.length > 0" |
||||
|
flat |
||||
|
size="16px" |
||||
|
dense |
||||
|
padding="0px 0px" |
||||
|
:icon="data.expand ? 'bi-dash' : 'bi-plus'" |
||||
|
@click="data.expand = !data.expand" |
||||
|
/> |
||||
|
<!--展开按钮占位符--> |
||||
|
<span v-else style="width: 27px"></span> |
||||
|
<!--选择框--> |
||||
|
<q-checkbox v-model="data.selected" flat size="40px" dense /> |
||||
|
<!--文件夹图标--> |
||||
|
<q-icon v-if="data.children && data.children.length > 0" name="sym_o_folder_open" size="20px" class="px-1"></q-icon> |
||||
|
<!--文件图标--> |
||||
|
<q-icon v-else name="bi-file-earmark" size="16px" class="px-1"></q-icon> |
||||
|
</template> |
||||
|
<div v-dompurify-html="col.format ? col.format(data[col.name], data) : col.value"></div> |
||||
|
</div> |
||||
|
</q-td> |
||||
|
</q-tr> |
||||
|
<template v-for="child in data.children" :key="child.id"> |
||||
|
<TableRow v-if="data.expand" :cols="cols" :data="child" :level="props.level + 1"></TableRow> |
||||
|
</template> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
const props = defineProps({ |
||||
|
level: { type: Number, default: 0 }, |
||||
|
cols: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
data: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
const cols = props.cols; |
||||
|
const data = props.data; |
||||
|
</script> |
@ -1,53 +1,54 @@ |
|||||
<template> |
<template> |
||||
<div> |
<w-list-grid |
||||
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> |
:tree="true" |
||||
</div> |
title="User List" |
||||
|
:no-action-icon="true" |
||||
|
:target-object-name="$t('菜单')" |
||||
|
:actions="[ |
||||
|
'query', |
||||
|
'refresh', |
||||
|
'expandAll', |
||||
|
'selectAll', |
||||
|
'separator', |
||||
|
'add', |
||||
|
'clone', |
||||
|
'edit', |
||||
|
'remove', |
||||
|
'removeAll', |
||||
|
'separator', |
||||
|
'detail', |
||||
|
|
||||
|
'addTop', |
||||
|
'addChild', |
||||
|
]" |
||||
|
:columns="columns" |
||||
|
:auto-fetch-data="true" |
||||
|
:data-url="Environment.apiContextPath('/api/system/menu/allMenus')" |
||||
|
></w-list-grid> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { ref, onMounted, toRaw } from 'vue'; |
import { ref } from 'vue'; |
||||
import { useRoute } from 'vue-router'; |
|
||||
import { useI18n } from 'vue-i18n'; |
import { useI18n } from 'vue-i18n'; |
||||
import { Environment, axios } from '@/platform'; |
import { Environment } from '@/platform'; |
||||
|
|
||||
const route = useRoute(); |
|
||||
const { t } = useI18n(); |
const { t } = useI18n(); |
||||
|
|
||||
const corporationTreeGridRef = ref(); |
const columns = [ |
||||
|
|
||||
const corporationConfigure = { |
|
||||
actions: [ |
|
||||
{ |
{ |
||||
name: 'refresh', |
name: 'name', |
||||
label: t('refresh'), |
required: true, |
||||
click: () => {}, |
label: 'Dessert (100g serving)', |
||||
|
align: 'left', |
||||
|
field: 'name', |
||||
|
sortable: true, |
||||
}, |
}, |
||||
|
{ name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, |
||||
{ |
{ name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, |
||||
name: 'addRoot', |
{ name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, |
||||
label: t('system.corporation.action.addTop'), |
{ name: 'protein', label: 'Protein (g)', field: 'protein' }, |
||||
click: () => {}, |
{ name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, |
||||
}, |
{ name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, |
||||
{ |
{ name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, |
||||
name: 'addChild', |
]; |
||||
label: t('system.corporation.action.addChild'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'edit', |
|
||||
label: t('edit'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'delete', |
|
||||
label: t('delete'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
|
||||
|
|
||||
onMounted(() => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => { |
|
||||
corporationTreeGridRef.value.setNodes(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
</script> |
</script> |
||||
|
@ -0,0 +1,118 @@ |
|||||
|
<template> |
||||
|
<div class="flex flex-nowrap py-2"> |
||||
|
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div> |
||||
|
<q-space /> |
||||
|
<div ref="actionContainerRef" class="flex flex-nowrap"> |
||||
|
<!-- baseActions --> |
||||
|
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index"> |
||||
|
<q-separator |
||||
|
v-if="action.separator" |
||||
|
vertical |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
/> |
||||
|
<q-btn |
||||
|
v-else |
||||
|
v-bind="action" |
||||
|
:id="action.name" |
||||
|
:disable="action.enableIf ? !action.enableIf() : false" |
||||
|
no-wrap |
||||
|
class="class-action-item" |
||||
|
:style="{ |
||||
|
'margin-left': '5px', |
||||
|
'margin-right': '5px', |
||||
|
}" |
||||
|
@click="action.click" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<!-- moreActions --> |
||||
|
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px"> |
||||
|
<q-list> |
||||
|
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index"> |
||||
|
<q-separator v-if="action.separator" /> |
||||
|
<q-item v-else v-close-popup clickable @click="action.click"> |
||||
|
<q-item-section avatar style="min-width: 28px; padding-right: 0px"> |
||||
|
<q-icon :name="action.icon" size="20px" /> |
||||
|
</q-item-section> |
||||
|
<q-item-section> |
||||
|
<q-item-label :v-bind="action">{{ action.label }}</q-item-label> |
||||
|
</q-item-section> |
||||
|
</q-item> |
||||
|
</template> |
||||
|
</q-list> |
||||
|
</q-btn-dropdown> |
||||
|
</div> |
||||
|
<q-resize-observer @resize="onResize" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Tools } from '@/platform/utils'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
title: { type: String, default: '' }, |
||||
|
actions: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const titleContainerRef = ref(); |
||||
|
const actionContainerRef = ref(); |
||||
|
|
||||
|
const actions = props.actions; |
||||
|
const baseActions = ref(actions); |
||||
|
const moreActions = ref([]); |
||||
|
const isActionWidthInitializedRef = ref(false); |
||||
|
const moreActionWidth = 100; |
||||
|
|
||||
|
const onResize = (size) => { |
||||
|
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!isActionWidthInitializedRef.value) { |
||||
|
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item'); |
||||
|
for (let i = 0; i < actions.length; i++) { |
||||
|
actions[i].width = nodes[i].clientWidth + 10; |
||||
|
} |
||||
|
isActionWidthInitializedRef.value = true; |
||||
|
} |
||||
|
|
||||
|
const _baseActions = []; |
||||
|
const _moreActions = []; |
||||
|
const length = actions.length; |
||||
|
let availableWidth = size.width - titleContainerRef.value.clientWidth; |
||||
|
let width = 0; |
||||
|
let index = 0; |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
console.log(index, width + actions[index].width, availableWidth); |
||||
|
if (width + actions[index].width > availableWidth) { |
||||
|
availableWidth -= moreActionWidth; |
||||
|
while (width > availableWidth) { |
||||
|
index--; |
||||
|
width -= actions[index].width; |
||||
|
_baseActions.pop(); |
||||
|
} |
||||
|
break; |
||||
|
} else { |
||||
|
_baseActions.push(actions[index]); |
||||
|
width += actions[index].width; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for (; index < length; index++) { |
||||
|
_moreActions.push(actions[index]); |
||||
|
} |
||||
|
|
||||
|
baseActions.value = _baseActions; |
||||
|
moreActions.value = _moreActions; |
||||
|
}; |
||||
|
</script> |
@ -0,0 +1,6 @@ |
|||||
|
dependencies { |
||||
|
api( |
||||
|
project(":io.sc.platform.core"), |
||||
|
project(":io.sc.platform.orm.api"), |
||||
|
) |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum BlockStrategy { |
||||
|
SERIAL_EXECUTION, //单机串行
|
||||
|
DISCARD_LATER, //丢弃后续调度
|
||||
|
COVER_EARLY; //覆盖先前调度
|
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum ExecutorRouteStrategy { |
||||
|
FIRST, //第一个
|
||||
|
LAST, //最后一个
|
||||
|
ROUND, //轮询
|
||||
|
RANDOM, //随机
|
||||
|
CONSISTENT_HASH, //一致性 Hash
|
||||
|
LEAST_FREQUENTLY_USED, //最不经常使用
|
||||
|
LEAST_RECENTLY_USED, //最近最久未使用
|
||||
|
FAILOVER, //故障转移
|
||||
|
BUSYOVER, //忙碌转义
|
||||
|
SHARDING_BROADCAST; //分片广播
|
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum ExpirationPolicy { |
||||
|
DO_NOTHING, //忽略
|
||||
|
FIRE_ONCE_NOW; //立即执行一次
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum GlueType { |
||||
|
BEAN, // Bean
|
||||
|
GLUE_GROOVY, // groovy
|
||||
|
GLUE_SHELL, // shell
|
||||
|
GLUE_PYTHON, // python
|
||||
|
GLUE_PHP, // php
|
||||
|
GLUE_NODEJS, // nodejs
|
||||
|
GLUE_POWERSHELL;// powershell
|
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum TaskScheduleType { |
||||
|
NONE, //无
|
||||
|
CRON, //Cron
|
||||
|
FIX_RATE; //固定周期
|
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
package io.sc.platform.job.core.enums; |
||||
|
|
||||
|
public enum TriggerStatus { |
||||
|
STOPED, //已停止
|
||||
|
RUNNING; //运行中
|
||||
|
} |
@ -0,0 +1,179 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.complete.XxlJobCompleter; |
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.model.XxlJobLog; |
||||
|
import com.xxl.job.admin.core.util.I18nUtil; |
||||
|
import com.xxl.job.core.biz.model.HandleCallbackParam; |
||||
|
import com.xxl.job.core.biz.model.ReturnT; |
||||
|
import com.xxl.job.core.util.DateUtil; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.*; |
||||
|
|
||||
|
public class JobCompleteHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class); |
||||
|
|
||||
|
private static JobCompleteHelper instance = new JobCompleteHelper(); |
||||
|
public static JobCompleteHelper getInstance(){ |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
// ---------------------- monitor ----------------------
|
||||
|
|
||||
|
private ThreadPoolExecutor callbackThreadPool = null; |
||||
|
private Thread monitorThread; |
||||
|
private volatile boolean toStop = false; |
||||
|
public void start(){ |
||||
|
|
||||
|
// for callback
|
||||
|
callbackThreadPool = new ThreadPoolExecutor( |
||||
|
2, |
||||
|
20, |
||||
|
30L, |
||||
|
TimeUnit.SECONDS, |
||||
|
new LinkedBlockingQueue<Runnable>(3000), |
||||
|
new ThreadFactory() { |
||||
|
@Override |
||||
|
public Thread newThread(Runnable r) { |
||||
|
return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode()); |
||||
|
} |
||||
|
}, |
||||
|
new RejectedExecutionHandler() { |
||||
|
@Override |
||||
|
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { |
||||
|
r.run(); |
||||
|
logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now)."); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
// for monitor
|
||||
|
monitorThread = new Thread(new Runnable() { |
||||
|
|
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
// wait for JobTriggerPoolHelper-init
|
||||
|
try { |
||||
|
TimeUnit.MILLISECONDS.sleep(50); |
||||
|
} catch (InterruptedException e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// monitor
|
||||
|
while (!toStop) { |
||||
|
try { |
||||
|
// 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败;
|
||||
|
Date losedTime = DateUtil.addMinutes(new Date(), -10); |
||||
|
List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime); |
||||
|
|
||||
|
if (losedJobIds!=null && losedJobIds.size()>0) { |
||||
|
for (Long logId: losedJobIds) { |
||||
|
|
||||
|
XxlJobLog jobLog = new XxlJobLog(); |
||||
|
jobLog.setId(logId); |
||||
|
|
||||
|
jobLog.setHandleTime(new Date()); |
||||
|
jobLog.setHandleCode(ReturnT.FAIL_CODE); |
||||
|
jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") ); |
||||
|
|
||||
|
XxlJobCompleter.updateHandleInfoAndFinish(jobLog); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(60); |
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop"); |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
monitorThread.setDaemon(true); |
||||
|
monitorThread.setName("xxl-job, admin JobLosedMonitorHelper"); |
||||
|
monitorThread.start(); |
||||
|
} |
||||
|
|
||||
|
public void toStop(){ |
||||
|
toStop = true; |
||||
|
|
||||
|
// stop registryOrRemoveThreadPool
|
||||
|
callbackThreadPool.shutdownNow(); |
||||
|
|
||||
|
// stop monitorThread (interrupt and wait)
|
||||
|
monitorThread.interrupt(); |
||||
|
try { |
||||
|
monitorThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ---------------------- helper ----------------------
|
||||
|
|
||||
|
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) { |
||||
|
|
||||
|
callbackThreadPool.execute(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
for (HandleCallbackParam handleCallbackParam: callbackParamList) { |
||||
|
ReturnT<String> callbackResult = callback(handleCallbackParam); |
||||
|
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}", |
||||
|
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return ReturnT.SUCCESS; |
||||
|
} |
||||
|
|
||||
|
private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) { |
||||
|
// valid log item
|
||||
|
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId()); |
||||
|
if (log == null) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found."); |
||||
|
} |
||||
|
if (log.getHandleCode() > 0) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc
|
||||
|
} |
||||
|
|
||||
|
// handle msg
|
||||
|
StringBuffer handleMsg = new StringBuffer(); |
||||
|
if (log.getHandleMsg()!=null) { |
||||
|
handleMsg.append(log.getHandleMsg()).append("<br>"); |
||||
|
} |
||||
|
if (handleCallbackParam.getHandleMsg() != null) { |
||||
|
handleMsg.append(handleCallbackParam.getHandleMsg()); |
||||
|
} |
||||
|
|
||||
|
// success, save log
|
||||
|
log.setHandleTime(new Date()); |
||||
|
log.setHandleCode(handleCallbackParam.getHandleCode()); |
||||
|
log.setHandleMsg(handleMsg.toString()); |
||||
|
XxlJobCompleter.updateHandleInfoAndFinish(log); |
||||
|
|
||||
|
return ReturnT.SUCCESS; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,110 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.model.XxlJobInfo; |
||||
|
import com.xxl.job.admin.core.model.XxlJobLog; |
||||
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum; |
||||
|
import com.xxl.job.admin.core.util.I18nUtil; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
/** |
||||
|
* job monitor instance |
||||
|
* |
||||
|
* @author xuxueli 2015-9-1 18:05:56 |
||||
|
*/ |
||||
|
public class JobFailMonitorHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class); |
||||
|
|
||||
|
private static JobFailMonitorHelper instance = new JobFailMonitorHelper(); |
||||
|
public static JobFailMonitorHelper getInstance(){ |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
// ---------------------- monitor ----------------------
|
||||
|
|
||||
|
private Thread monitorThread; |
||||
|
private volatile boolean toStop = false; |
||||
|
public void start(){ |
||||
|
monitorThread = new Thread(new Runnable() { |
||||
|
|
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
// monitor
|
||||
|
while (!toStop) { |
||||
|
try { |
||||
|
|
||||
|
List<Long> failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000); |
||||
|
if (failLogIds!=null && !failLogIds.isEmpty()) { |
||||
|
for (long failLogId: failLogIds) { |
||||
|
|
||||
|
// lock log
|
||||
|
int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1); |
||||
|
if (lockRet < 1) { |
||||
|
continue; |
||||
|
} |
||||
|
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId); |
||||
|
XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId()); |
||||
|
|
||||
|
// 1、fail retry monitor
|
||||
|
if (log.getExecutorFailRetryCount() > 0) { |
||||
|
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam(), null); |
||||
|
String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>"; |
||||
|
log.setTriggerMsg(log.getTriggerMsg() + retryMsg); |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log); |
||||
|
} |
||||
|
|
||||
|
// 2、fail alarm monitor
|
||||
|
int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
|
||||
|
if (info != null) { |
||||
|
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log); |
||||
|
newAlarmStatus = alarmResult?2:3; |
||||
|
} else { |
||||
|
newAlarmStatus = 1; |
||||
|
} |
||||
|
|
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(10); |
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop"); |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
monitorThread.setDaemon(true); |
||||
|
monitorThread.setName("xxl-job, admin JobFailMonitorHelper"); |
||||
|
monitorThread.start(); |
||||
|
} |
||||
|
|
||||
|
public void toStop(){ |
||||
|
toStop = true; |
||||
|
// interrupt and wait
|
||||
|
monitorThread.interrupt(); |
||||
|
try { |
||||
|
monitorThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,152 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.model.XxlJobLogReport; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.util.Calendar; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
/** |
||||
|
* job log report helper |
||||
|
* |
||||
|
* @author xuxueli 2019-11-22 |
||||
|
*/ |
||||
|
public class JobLogReportHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class); |
||||
|
|
||||
|
private static JobLogReportHelper instance = new JobLogReportHelper(); |
||||
|
public static JobLogReportHelper getInstance(){ |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private Thread logrThread; |
||||
|
private volatile boolean toStop = false; |
||||
|
public void start(){ |
||||
|
logrThread = new Thread(new Runnable() { |
||||
|
|
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
// last clean log time
|
||||
|
long lastCleanLogTime = 0; |
||||
|
|
||||
|
|
||||
|
while (!toStop) { |
||||
|
|
||||
|
// 1、log-report refresh: refresh log report in 3 days
|
||||
|
try { |
||||
|
|
||||
|
for (int i = 0; i < 3; i++) { |
||||
|
|
||||
|
// today
|
||||
|
Calendar itemDay = Calendar.getInstance(); |
||||
|
itemDay.add(Calendar.DAY_OF_MONTH, -i); |
||||
|
itemDay.set(Calendar.HOUR_OF_DAY, 0); |
||||
|
itemDay.set(Calendar.MINUTE, 0); |
||||
|
itemDay.set(Calendar.SECOND, 0); |
||||
|
itemDay.set(Calendar.MILLISECOND, 0); |
||||
|
|
||||
|
Date todayFrom = itemDay.getTime(); |
||||
|
|
||||
|
itemDay.set(Calendar.HOUR_OF_DAY, 23); |
||||
|
itemDay.set(Calendar.MINUTE, 59); |
||||
|
itemDay.set(Calendar.SECOND, 59); |
||||
|
itemDay.set(Calendar.MILLISECOND, 999); |
||||
|
|
||||
|
Date todayTo = itemDay.getTime(); |
||||
|
|
||||
|
// refresh log-report every minute
|
||||
|
XxlJobLogReport xxlJobLogReport = new XxlJobLogReport(); |
||||
|
xxlJobLogReport.setTriggerDay(todayFrom); |
||||
|
xxlJobLogReport.setRunningCount(0); |
||||
|
xxlJobLogReport.setSucCount(0); |
||||
|
xxlJobLogReport.setFailCount(0); |
||||
|
|
||||
|
Map<String, Object> triggerCountMap = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLogReport(todayFrom, todayTo); |
||||
|
if (triggerCountMap!=null && triggerCountMap.size()>0) { |
||||
|
int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0; |
||||
|
int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0; |
||||
|
int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0; |
||||
|
int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; |
||||
|
|
||||
|
xxlJobLogReport.setRunningCount(triggerDayCountRunning); |
||||
|
xxlJobLogReport.setSucCount(triggerDayCountSuc); |
||||
|
xxlJobLogReport.setFailCount(triggerDayCountFail); |
||||
|
} |
||||
|
|
||||
|
// do refresh
|
||||
|
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().update(xxlJobLogReport); |
||||
|
if (ret < 1) { |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().save(xxlJobLogReport); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 2、log-clean: switch open & once each day
|
||||
|
if (XxlJobAdminConfig.getAdminConfig().getLogretentiondays()>0 |
||||
|
&& System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000) { |
||||
|
|
||||
|
// expire-time
|
||||
|
Calendar expiredDay = Calendar.getInstance(); |
||||
|
expiredDay.add(Calendar.DAY_OF_MONTH, -1 * XxlJobAdminConfig.getAdminConfig().getLogretentiondays()); |
||||
|
expiredDay.set(Calendar.HOUR_OF_DAY, 0); |
||||
|
expiredDay.set(Calendar.MINUTE, 0); |
||||
|
expiredDay.set(Calendar.SECOND, 0); |
||||
|
expiredDay.set(Calendar.MILLISECOND, 0); |
||||
|
Date clearBeforeTime = expiredDay.getTime(); |
||||
|
|
||||
|
// clean expired log
|
||||
|
List<Long> logIds = null; |
||||
|
do { |
||||
|
logIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findClearLogIds(0, 0, clearBeforeTime, 0, 1000); |
||||
|
if (logIds!=null && logIds.size()>0) { |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().clearLog(logIds); |
||||
|
} |
||||
|
} while (logIds!=null && logIds.size()>0); |
||||
|
|
||||
|
// update clean time
|
||||
|
lastCleanLogTime = System.currentTimeMillis(); |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
TimeUnit.MINUTES.sleep(1); |
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
logger.info(">>>>>>>>>>> xxl-job, job log report thread stop"); |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
logrThread.setDaemon(true); |
||||
|
logrThread.setName("xxl-job, admin JobLogReportHelper"); |
||||
|
logrThread.start(); |
||||
|
} |
||||
|
|
||||
|
public void toStop(){ |
||||
|
toStop = true; |
||||
|
// interrupt and wait
|
||||
|
logrThread.interrupt(); |
||||
|
try { |
||||
|
logrThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,204 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.model.XxlJobGroup; |
||||
|
import com.xxl.job.admin.core.model.XxlJobRegistry; |
||||
|
import com.xxl.job.core.biz.model.RegistryParam; |
||||
|
import com.xxl.job.core.biz.model.ReturnT; |
||||
|
import com.xxl.job.core.enums.RegistryConfig; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
import java.util.*; |
||||
|
import java.util.concurrent.*; |
||||
|
|
||||
|
/** |
||||
|
* job registry instance |
||||
|
* @author xuxueli 2016-10-02 19:10:24 |
||||
|
*/ |
||||
|
public class JobRegistryHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class); |
||||
|
|
||||
|
private static JobRegistryHelper instance = new JobRegistryHelper(); |
||||
|
public static JobRegistryHelper getInstance(){ |
||||
|
return instance; |
||||
|
} |
||||
|
|
||||
|
private ThreadPoolExecutor registryOrRemoveThreadPool = null; |
||||
|
private Thread registryMonitorThread; |
||||
|
private volatile boolean toStop = false; |
||||
|
|
||||
|
public void start(){ |
||||
|
|
||||
|
// for registry or remove
|
||||
|
registryOrRemoveThreadPool = new ThreadPoolExecutor( |
||||
|
2, |
||||
|
10, |
||||
|
30L, |
||||
|
TimeUnit.SECONDS, |
||||
|
new LinkedBlockingQueue<Runnable>(2000), |
||||
|
new ThreadFactory() { |
||||
|
@Override |
||||
|
public Thread newThread(Runnable r) { |
||||
|
return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode()); |
||||
|
} |
||||
|
}, |
||||
|
new RejectedExecutionHandler() { |
||||
|
@Override |
||||
|
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { |
||||
|
r.run(); |
||||
|
logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now)."); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// for monitor
|
||||
|
registryMonitorThread = new Thread(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
while (!toStop) { |
||||
|
try { |
||||
|
// auto registry group
|
||||
|
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0); |
||||
|
if (groupList!=null && !groupList.isEmpty()) { |
||||
|
|
||||
|
// remove dead address (admin/executor)
|
||||
|
List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date()); |
||||
|
if (ids!=null && ids.size()>0) { |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids); |
||||
|
} |
||||
|
|
||||
|
// fresh online address (admin/executor)
|
||||
|
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>(); |
||||
|
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); |
||||
|
if (list != null) { |
||||
|
for (XxlJobRegistry item: list) { |
||||
|
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { |
||||
|
String appname = item.getRegistryKey(); |
||||
|
List<String> registryList = appAddressMap.get(appname); |
||||
|
if (registryList == null) { |
||||
|
registryList = new ArrayList<String>(); |
||||
|
} |
||||
|
|
||||
|
if (!registryList.contains(item.getRegistryValue())) { |
||||
|
registryList.add(item.getRegistryValue()); |
||||
|
} |
||||
|
appAddressMap.put(appname, registryList); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// fresh group address
|
||||
|
for (XxlJobGroup group: groupList) { |
||||
|
List<String> registryList = appAddressMap.get(group.getAppname()); |
||||
|
String addressListStr = null; |
||||
|
if (registryList!=null && !registryList.isEmpty()) { |
||||
|
Collections.sort(registryList); |
||||
|
StringBuilder addressListSB = new StringBuilder(); |
||||
|
for (String item:registryList) { |
||||
|
addressListSB.append(item).append(","); |
||||
|
} |
||||
|
addressListStr = addressListSB.toString(); |
||||
|
addressListStr = addressListStr.substring(0, addressListStr.length()-1); |
||||
|
} |
||||
|
group.setAddressList(addressListStr); |
||||
|
group.setUpdateTime(new Date()); |
||||
|
|
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group); |
||||
|
} |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT); |
||||
|
} catch (InterruptedException e) { |
||||
|
if (!toStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop"); |
||||
|
} |
||||
|
}); |
||||
|
registryMonitorThread.setDaemon(true); |
||||
|
registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread"); |
||||
|
registryMonitorThread.start(); |
||||
|
} |
||||
|
|
||||
|
public void toStop(){ |
||||
|
toStop = true; |
||||
|
|
||||
|
// stop registryOrRemoveThreadPool
|
||||
|
registryOrRemoveThreadPool.shutdownNow(); |
||||
|
|
||||
|
// stop monitir (interrupt and wait)
|
||||
|
registryMonitorThread.interrupt(); |
||||
|
try { |
||||
|
registryMonitorThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ---------------------- helper ----------------------
|
||||
|
|
||||
|
public ReturnT<String> registry(RegistryParam registryParam) { |
||||
|
|
||||
|
// valid
|
||||
|
if (!StringUtils.hasText(registryParam.getRegistryGroup()) |
||||
|
|| !StringUtils.hasText(registryParam.getRegistryKey()) |
||||
|
|| !StringUtils.hasText(registryParam.getRegistryValue())) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument."); |
||||
|
} |
||||
|
|
||||
|
// async execute
|
||||
|
registryOrRemoveThreadPool.execute(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); |
||||
|
if (ret < 1) { |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); |
||||
|
|
||||
|
// fresh
|
||||
|
freshGroupRegistryInfo(registryParam); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return ReturnT.SUCCESS; |
||||
|
} |
||||
|
|
||||
|
public ReturnT<String> registryRemove(RegistryParam registryParam) { |
||||
|
|
||||
|
// valid
|
||||
|
if (!StringUtils.hasText(registryParam.getRegistryGroup()) |
||||
|
|| !StringUtils.hasText(registryParam.getRegistryKey()) |
||||
|
|| !StringUtils.hasText(registryParam.getRegistryValue())) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument."); |
||||
|
} |
||||
|
|
||||
|
// async execute
|
||||
|
registryOrRemoveThreadPool.execute(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue()); |
||||
|
if (ret > 0) { |
||||
|
// fresh
|
||||
|
freshGroupRegistryInfo(registryParam); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return ReturnT.SUCCESS; |
||||
|
} |
||||
|
|
||||
|
private void freshGroupRegistryInfo(RegistryParam registryParam){ |
||||
|
// Under consideration, prevent affecting core tables
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,368 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.cron.CronExpression; |
||||
|
import com.xxl.job.admin.core.model.XxlJobInfo; |
||||
|
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; |
||||
|
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum; |
||||
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum; |
||||
|
import io.sc.platform.core.Environment; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.sql.Connection; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.*; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
public class JobScheduleHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class); |
||||
|
|
||||
|
public static final long PRE_READ_MS = 5000; // pre read
|
||||
|
private Thread scheduleThread; |
||||
|
private Thread ringThread; |
||||
|
private volatile boolean scheduleThreadToStop = false; |
||||
|
private volatile boolean ringThreadToStop = false; |
||||
|
private volatile static Map<Integer, List<Integer>> ringData = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
private static class JobScheduleHelperHolder{ |
||||
|
private static JobScheduleHelper instance =new JobScheduleHelper(); |
||||
|
} |
||||
|
|
||||
|
private JobScheduleHelper(){} |
||||
|
public static JobScheduleHelper getInstance(){ |
||||
|
return JobScheduleHelperHolder.instance; |
||||
|
} |
||||
|
|
||||
|
public void start(){ |
||||
|
// schedule thread
|
||||
|
scheduleThread = new Thread(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
try { |
||||
|
TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis()%1000 ); |
||||
|
} catch (InterruptedException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
logger.info(">>>>>>>>> init xxl-job admin scheduler success."); |
||||
|
|
||||
|
// pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
|
||||
|
int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20; |
||||
|
|
||||
|
while (!scheduleThreadToStop) { |
||||
|
|
||||
|
// Scan Job
|
||||
|
long start = System.currentTimeMillis(); |
||||
|
|
||||
|
Connection conn = null; |
||||
|
Boolean connAutoCommit = null; |
||||
|
PreparedStatement preparedStatement = null; |
||||
|
|
||||
|
boolean preReadSuc = true; |
||||
|
try { |
||||
|
|
||||
|
conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection(); |
||||
|
connAutoCommit = conn.getAutoCommit(); |
||||
|
conn.setAutoCommit(false); |
||||
|
|
||||
|
preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" ); |
||||
|
preparedStatement.execute(); |
||||
|
|
||||
|
// tx start
|
||||
|
|
||||
|
// 1、pre read
|
||||
|
long nowTime = System.currentTimeMillis(); |
||||
|
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount); |
||||
|
if (scheduleList!=null && scheduleList.size()>0) { |
||||
|
// 2、push time-ring
|
||||
|
for (XxlJobInfo jobInfo: scheduleList) { |
||||
|
|
||||
|
// time-ring jump
|
||||
|
if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) { |
||||
|
// 2.1、trigger-expire > 5s:pass && make next-trigger-time
|
||||
|
logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId()); |
||||
|
|
||||
|
// 1、misfire match
|
||||
|
MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING); |
||||
|
if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) { |
||||
|
// FIRE_ONCE_NOW 》 trigger
|
||||
|
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null); |
||||
|
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); |
||||
|
} |
||||
|
|
||||
|
// 2、fresh next
|
||||
|
refreshNextValidTime(jobInfo, new Date()); |
||||
|
|
||||
|
} else if (nowTime > jobInfo.getTriggerNextTime()) { |
||||
|
// 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
|
||||
|
|
||||
|
// 1、trigger
|
||||
|
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null, null); |
||||
|
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); |
||||
|
|
||||
|
// 2、fresh next
|
||||
|
refreshNextValidTime(jobInfo, new Date()); |
||||
|
|
||||
|
// next-trigger-time in 5s, pre-read again
|
||||
|
if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) { |
||||
|
|
||||
|
// 1、make ring second
|
||||
|
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); |
||||
|
|
||||
|
// 2、push time ring
|
||||
|
pushTimeRing(ringSecond, jobInfo.getId()); |
||||
|
|
||||
|
// 3、fresh next
|
||||
|
refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
// 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time
|
||||
|
|
||||
|
// 1、make ring second
|
||||
|
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); |
||||
|
|
||||
|
// 2、push time ring
|
||||
|
pushTimeRing(ringSecond, jobInfo.getId()); |
||||
|
|
||||
|
// 3、fresh next
|
||||
|
refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 3、update trigger info
|
||||
|
for (XxlJobInfo jobInfo: scheduleList) { |
||||
|
XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo); |
||||
|
} |
||||
|
|
||||
|
} else { |
||||
|
preReadSuc = false; |
||||
|
} |
||||
|
|
||||
|
// tx stop
|
||||
|
|
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e); |
||||
|
} |
||||
|
} finally { |
||||
|
|
||||
|
// commit
|
||||
|
if (conn != null) { |
||||
|
try { |
||||
|
conn.commit(); |
||||
|
} catch (SQLException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
try { |
||||
|
conn.setAutoCommit(connAutoCommit); |
||||
|
} catch (SQLException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
try { |
||||
|
conn.close(); |
||||
|
} catch (SQLException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// close PreparedStatement
|
||||
|
if (null != preparedStatement) { |
||||
|
try { |
||||
|
preparedStatement.close(); |
||||
|
} catch (SQLException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
long cost = System.currentTimeMillis()-start; |
||||
|
|
||||
|
|
||||
|
// Wait seconds, align second
|
||||
|
if (cost < 1000) { // scan-overtime, not wait
|
||||
|
try { |
||||
|
// pre-read period: success > scan each second; fail > skip this period;
|
||||
|
TimeUnit.MILLISECONDS.sleep((preReadSuc?1000:PRE_READ_MS) - System.currentTimeMillis()%1000); |
||||
|
} catch (InterruptedException e) { |
||||
|
if (!scheduleThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop"); |
||||
|
} |
||||
|
}); |
||||
|
scheduleThread.setDaemon(true); |
||||
|
scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread"); |
||||
|
scheduleThread.start(); |
||||
|
|
||||
|
|
||||
|
// ring thread
|
||||
|
ringThread = new Thread(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
while (!ringThreadToStop) { |
||||
|
|
||||
|
// align second
|
||||
|
try { |
||||
|
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000); |
||||
|
} catch (InterruptedException e) { |
||||
|
if (!ringThreadToStop) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
// second data
|
||||
|
List<Integer> ringItemData = new ArrayList<>(); |
||||
|
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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ring trigger
|
||||
|
logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) ); |
||||
|
if (ringItemData.size() > 0) { |
||||
|
// do trigger
|
||||
|
for (int jobId: ringItemData) { |
||||
|
// do trigger
|
||||
|
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null, null); |
||||
|
} |
||||
|
// clear
|
||||
|
ringItemData.clear(); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
if (!ringThreadToStop) { |
||||
|
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop"); |
||||
|
} |
||||
|
}); |
||||
|
ringThread.setDaemon(true); |
||||
|
ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread"); |
||||
|
ringThread.start(); |
||||
|
} |
||||
|
|
||||
|
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { |
||||
|
Date nextValidTime = generateNextValidTime(jobInfo, fromTime); |
||||
|
if (nextValidTime != null) { |
||||
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime()); |
||||
|
jobInfo.setTriggerNextTime(nextValidTime.getTime()); |
||||
|
} else { |
||||
|
jobInfo.setTriggerStatus(0); |
||||
|
jobInfo.setTriggerLastTime(0); |
||||
|
jobInfo.setTriggerNextTime(0); |
||||
|
logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}", |
||||
|
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void pushTimeRing(int ringSecond, int jobId){ |
||||
|
// push async ring
|
||||
|
List<Integer> ringItemData = ringData.get(ringSecond); |
||||
|
if (ringItemData == null) { |
||||
|
ringItemData = new ArrayList<Integer>(); |
||||
|
ringData.put(ringSecond, ringItemData); |
||||
|
} |
||||
|
ringItemData.add(jobId); |
||||
|
|
||||
|
logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) ); |
||||
|
} |
||||
|
|
||||
|
public void toStop(){ |
||||
|
|
||||
|
// 1、stop schedule
|
||||
|
scheduleThreadToStop = true; |
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(1); // wait
|
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
if (scheduleThread.getState() != Thread.State.TERMINATED){ |
||||
|
// interrupt and wait
|
||||
|
scheduleThread.interrupt(); |
||||
|
try { |
||||
|
scheduleThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// if has ring data
|
||||
|
boolean hasRingData = false; |
||||
|
if (!ringData.isEmpty()) { |
||||
|
for (int second : ringData.keySet()) { |
||||
|
List<Integer> tmpData = ringData.get(second); |
||||
|
if (tmpData!=null && tmpData.size()>0) { |
||||
|
hasRingData = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (hasRingData) { |
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(8); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// stop ring (wait job-in-memory stop)
|
||||
|
ringThreadToStop = true; |
||||
|
try { |
||||
|
TimeUnit.SECONDS.sleep(1); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
if (ringThread.getState() != Thread.State.TERMINATED){ |
||||
|
// interrupt and wait
|
||||
|
ringThread.interrupt(); |
||||
|
try { |
||||
|
ringThread.join(); |
||||
|
} catch (InterruptedException e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper stop"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ---------------------- tools ----------------------
|
||||
|
public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { |
||||
|
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); |
||||
|
if (ScheduleTypeEnum.CRON == scheduleTypeEnum) { |
||||
|
Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime); |
||||
|
return nextValidTime; |
||||
|
} else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) { |
||||
|
return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 ); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,150 @@ |
|||||
|
package io.sc.platform.job.core.thread; |
||||
|
|
||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig; |
||||
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum; |
||||
|
import com.xxl.job.admin.core.trigger.XxlJobTrigger; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.util.concurrent.*; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
|
||||
|
/** |
||||
|
* job trigger thread pool helper |
||||
|
* |
||||
|
* @author xuxueli 2018-07-03 21:08:07 |
||||
|
*/ |
||||
|
public class JobTriggerPoolHelper { |
||||
|
private static Logger logger = LoggerFactory.getLogger(JobTriggerPoolHelper.class); |
||||
|
|
||||
|
|
||||
|
// ---------------------- trigger pool ----------------------
|
||||
|
|
||||
|
// fast/slow thread pool
|
||||
|
private ThreadPoolExecutor fastTriggerPool = null; |
||||
|
private ThreadPoolExecutor slowTriggerPool = null; |
||||
|
|
||||
|
public void start(){ |
||||
|
fastTriggerPool = new ThreadPoolExecutor( |
||||
|
10, |
||||
|
XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(), |
||||
|
60L, |
||||
|
TimeUnit.SECONDS, |
||||
|
new LinkedBlockingQueue<Runnable>(1000), |
||||
|
new ThreadFactory() { |
||||
|
@Override |
||||
|
public Thread newThread(Runnable r) { |
||||
|
return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode()); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
slowTriggerPool = new ThreadPoolExecutor( |
||||
|
10, |
||||
|
XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(), |
||||
|
60L, |
||||
|
TimeUnit.SECONDS, |
||||
|
new LinkedBlockingQueue<Runnable>(2000), |
||||
|
new ThreadFactory() { |
||||
|
@Override |
||||
|
public Thread newThread(Runnable r) { |
||||
|
return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode()); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public void stop() { |
||||
|
//triggerPool.shutdown();
|
||||
|
fastTriggerPool.shutdownNow(); |
||||
|
slowTriggerPool.shutdownNow(); |
||||
|
logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success."); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// job timeout count
|
||||
|
private volatile long minTim = System.currentTimeMillis()/60000; // ms > min
|
||||
|
private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* add trigger |
||||
|
*/ |
||||
|
public void addTrigger(final int jobId, |
||||
|
final TriggerTypeEnum triggerType, |
||||
|
final int failRetryCount, |
||||
|
final String executorShardingParam, |
||||
|
final String executorParam, |
||||
|
final String addressList) { |
||||
|
|
||||
|
// choose thread pool
|
||||
|
ThreadPoolExecutor triggerPool_ = fastTriggerPool; |
||||
|
AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId); |
||||
|
if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min
|
||||
|
triggerPool_ = slowTriggerPool; |
||||
|
} |
||||
|
|
||||
|
// trigger
|
||||
|
triggerPool_.execute(new Runnable() { |
||||
|
@Override |
||||
|
public void run() { |
||||
|
|
||||
|
long start = System.currentTimeMillis(); |
||||
|
|
||||
|
try { |
||||
|
// do trigger
|
||||
|
XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); |
||||
|
} catch (Exception e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
} finally { |
||||
|
|
||||
|
// check timeout-count-map
|
||||
|
long minTim_now = System.currentTimeMillis()/60000; |
||||
|
if (minTim != minTim_now) { |
||||
|
minTim = minTim_now; |
||||
|
jobTimeoutCountMap.clear(); |
||||
|
} |
||||
|
|
||||
|
// incr timeout-count-map
|
||||
|
long cost = System.currentTimeMillis()-start; |
||||
|
if (cost > 500) { // ob-timeout threshold 500ms
|
||||
|
AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1)); |
||||
|
if (timeoutCount != null) { |
||||
|
timeoutCount.incrementAndGet(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
// ---------------------- helper ----------------------
|
||||
|
|
||||
|
private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper(); |
||||
|
|
||||
|
public static void toStart() { |
||||
|
helper.start(); |
||||
|
} |
||||
|
public static void toStop() { |
||||
|
helper.stop(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param jobId |
||||
|
* @param triggerType |
||||
|
* @param failRetryCount |
||||
|
* >=0: use this param |
||||
|
* <0: use param from job info config |
||||
|
* @param executorShardingParam |
||||
|
* @param executorParam |
||||
|
* null: use job param |
||||
|
* not null: cover job param |
||||
|
*/ |
||||
|
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) { |
||||
|
helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
package io.sc.platform.job.core.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class ExecutorRegistryVo extends BaseVo { |
||||
|
private String id; |
||||
|
private String registryGroup; |
||||
|
private String registryKey; |
||||
|
private String registryValue; |
||||
|
private Date updateTime; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryGroup() { |
||||
|
return registryGroup; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryGroup(String registryGroup) { |
||||
|
this.registryGroup = registryGroup; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryKey() { |
||||
|
return registryKey; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryKey(String registryKey) { |
||||
|
this.registryKey = registryKey; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryValue() { |
||||
|
return registryValue; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryValue(String registryValue) { |
||||
|
this.registryValue = registryValue; |
||||
|
} |
||||
|
|
||||
|
public Date getUpdateTime() { |
||||
|
return updateTime; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateTime(Date updateTime) { |
||||
|
this.updateTime = updateTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
package io.sc.platform.job.core.vo; |
||||
|
|
||||
|
import io.sc.platform.job.core.enums.ExecutorAddressType; |
||||
|
import io.sc.platform.orm.api.vo.CorporationAuditorVo; |
||||
|
|
||||
|
import java.util.Set; |
||||
|
|
||||
|
public class ExecutorVo extends CorporationAuditorVo { |
||||
|
private String id; |
||||
|
private String appName; |
||||
|
private String name; |
||||
|
private String description; |
||||
|
private ExecutorAddressType addressType; |
||||
|
private Set<String> addresses; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getAppName() { |
||||
|
return appName; |
||||
|
} |
||||
|
|
||||
|
public void setAppName(String appName) { |
||||
|
this.appName = appName; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getDescription() { |
||||
|
return description; |
||||
|
} |
||||
|
|
||||
|
public void setDescription(String description) { |
||||
|
this.description = description; |
||||
|
} |
||||
|
|
||||
|
public ExecutorAddressType getAddressType() { |
||||
|
return addressType; |
||||
|
} |
||||
|
|
||||
|
public void setAddressType(ExecutorAddressType addressType) { |
||||
|
this.addressType = addressType; |
||||
|
} |
||||
|
|
||||
|
public Set<String> getAddresses() { |
||||
|
return addresses; |
||||
|
} |
||||
|
|
||||
|
public void setAddresses(Set<String> addresses) { |
||||
|
this.addresses = addresses; |
||||
|
} |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
package io.sc.platform.job.core.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class TaskLogReportVo extends BaseVo { |
||||
|
private String id; |
||||
|
private Date triggerDay; |
||||
|
private int runningCount; |
||||
|
private int sucCount; |
||||
|
private int failCount; |
||||
|
private Date updateTime; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public Date getTriggerDay() { |
||||
|
return triggerDay; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerDay(Date triggerDay) { |
||||
|
this.triggerDay = triggerDay; |
||||
|
} |
||||
|
|
||||
|
public int getRunningCount() { |
||||
|
return runningCount; |
||||
|
} |
||||
|
|
||||
|
public void setRunningCount(int runningCount) { |
||||
|
this.runningCount = runningCount; |
||||
|
} |
||||
|
|
||||
|
public int getSucCount() { |
||||
|
return sucCount; |
||||
|
} |
||||
|
|
||||
|
public void setSucCount(int sucCount) { |
||||
|
this.sucCount = sucCount; |
||||
|
} |
||||
|
|
||||
|
public int getFailCount() { |
||||
|
return failCount; |
||||
|
} |
||||
|
|
||||
|
public void setFailCount(int failCount) { |
||||
|
this.failCount = failCount; |
||||
|
} |
||||
|
|
||||
|
public Date getUpdateTime() { |
||||
|
return updateTime; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateTime(Date updateTime) { |
||||
|
this.updateTime = updateTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,143 @@ |
|||||
|
package io.sc.platform.job.core.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class TaskLogVo extends BaseVo { |
||||
|
private String id; |
||||
|
private String executorId; |
||||
|
private String taskId; |
||||
|
private String executorAddress; |
||||
|
private String executorHandler; |
||||
|
private String executorParam; |
||||
|
private String executorShardingParam; |
||||
|
private int executorFailRetryCount; |
||||
|
private Date triggerTime; |
||||
|
private int triggerCode; |
||||
|
private String triggerMsg; |
||||
|
private Date handleTime; |
||||
|
private int handleCode; |
||||
|
private String handleMsg; |
||||
|
private int alarmStatus; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorId() { |
||||
|
return executorId; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorId(String executorId) { |
||||
|
this.executorId = executorId; |
||||
|
} |
||||
|
|
||||
|
public String getTaskId() { |
||||
|
return taskId; |
||||
|
} |
||||
|
|
||||
|
public void setTaskId(String taskId) { |
||||
|
this.taskId = taskId; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorAddress() { |
||||
|
return executorAddress; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorAddress(String executorAddress) { |
||||
|
this.executorAddress = executorAddress; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorHandler() { |
||||
|
return executorHandler; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorHandler(String executorHandler) { |
||||
|
this.executorHandler = executorHandler; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorParam() { |
||||
|
return executorParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorParam(String executorParam) { |
||||
|
this.executorParam = executorParam; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorShardingParam() { |
||||
|
return executorShardingParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorShardingParam(String executorShardingParam) { |
||||
|
this.executorShardingParam = executorShardingParam; |
||||
|
} |
||||
|
|
||||
|
public int getExecutorFailRetryCount() { |
||||
|
return executorFailRetryCount; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorFailRetryCount(int executorFailRetryCount) { |
||||
|
this.executorFailRetryCount = executorFailRetryCount; |
||||
|
} |
||||
|
|
||||
|
public Date getTriggerTime() { |
||||
|
return triggerTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerTime(Date triggerTime) { |
||||
|
this.triggerTime = triggerTime; |
||||
|
} |
||||
|
|
||||
|
public int getTriggerCode() { |
||||
|
return triggerCode; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerCode(int triggerCode) { |
||||
|
this.triggerCode = triggerCode; |
||||
|
} |
||||
|
|
||||
|
public String getTriggerMsg() { |
||||
|
return triggerMsg; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerMsg(String triggerMsg) { |
||||
|
this.triggerMsg = triggerMsg; |
||||
|
} |
||||
|
|
||||
|
public Date getHandleTime() { |
||||
|
return handleTime; |
||||
|
} |
||||
|
|
||||
|
public void setHandleTime(Date handleTime) { |
||||
|
this.handleTime = handleTime; |
||||
|
} |
||||
|
|
||||
|
public int getHandleCode() { |
||||
|
return handleCode; |
||||
|
} |
||||
|
|
||||
|
public void setHandleCode(int handleCode) { |
||||
|
this.handleCode = handleCode; |
||||
|
} |
||||
|
|
||||
|
public String getHandleMsg() { |
||||
|
return handleMsg; |
||||
|
} |
||||
|
|
||||
|
public void setHandleMsg(String handleMsg) { |
||||
|
this.handleMsg = handleMsg; |
||||
|
} |
||||
|
|
||||
|
public int getAlarmStatus() { |
||||
|
return alarmStatus; |
||||
|
} |
||||
|
|
||||
|
public void setAlarmStatus(int alarmStatus) { |
||||
|
this.alarmStatus = alarmStatus; |
||||
|
} |
||||
|
} |
@ -0,0 +1,189 @@ |
|||||
|
package io.sc.platform.job.core.vo; |
||||
|
|
||||
|
import io.sc.platform.job.core.enums.*; |
||||
|
import io.sc.platform.orm.api.vo.CorporationAuditorVo; |
||||
|
|
||||
|
import java.util.Set; |
||||
|
|
||||
|
public class TaskVo extends CorporationAuditorVo { |
||||
|
private String id; |
||||
|
private String name; |
||||
|
private String description; |
||||
|
private String executor; |
||||
|
private String alarmEmail; |
||||
|
private TaskScheduleType scheduleType; |
||||
|
private String scheduleConf; |
||||
|
private ExpirationPolicy expirationPolicy; |
||||
|
private ExecutorRouteStrategy routeStrategy; |
||||
|
private String executorHandler; |
||||
|
private String executorParam; |
||||
|
private BlockStrategy blockStrategy; |
||||
|
private int timeout; |
||||
|
private int failRetryCount; |
||||
|
private GlueType glueType; |
||||
|
private String glueSource; |
||||
|
private String parent; |
||||
|
private TriggerStatus triggerStatus; |
||||
|
private long triggerLastTime; |
||||
|
private long triggerNextTime; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getDescription() { |
||||
|
return description; |
||||
|
} |
||||
|
|
||||
|
public void setDescription(String description) { |
||||
|
this.description = description; |
||||
|
} |
||||
|
|
||||
|
public String getExecutor() { |
||||
|
return executor; |
||||
|
} |
||||
|
|
||||
|
public void setExecutor(String executor) { |
||||
|
this.executor = executor; |
||||
|
} |
||||
|
|
||||
|
public String getAlarmEmail() { |
||||
|
return alarmEmail; |
||||
|
} |
||||
|
|
||||
|
public void setAlarmEmail(String alarmEmail) { |
||||
|
this.alarmEmail = alarmEmail; |
||||
|
} |
||||
|
|
||||
|
public TaskScheduleType getScheduleType() { |
||||
|
return scheduleType; |
||||
|
} |
||||
|
|
||||
|
public void setScheduleType(TaskScheduleType scheduleType) { |
||||
|
this.scheduleType = scheduleType; |
||||
|
} |
||||
|
|
||||
|
public String getScheduleConf() { |
||||
|
return scheduleConf; |
||||
|
} |
||||
|
|
||||
|
public void setScheduleConf(String scheduleConf) { |
||||
|
this.scheduleConf = scheduleConf; |
||||
|
} |
||||
|
|
||||
|
public ExpirationPolicy getExpirationPolicy() { |
||||
|
return expirationPolicy; |
||||
|
} |
||||
|
|
||||
|
public void setExpirationPolicy(ExpirationPolicy expirationPolicy) { |
||||
|
this.expirationPolicy = expirationPolicy; |
||||
|
} |
||||
|
|
||||
|
public ExecutorRouteStrategy getRouteStrategy() { |
||||
|
return routeStrategy; |
||||
|
} |
||||
|
|
||||
|
public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) { |
||||
|
this.routeStrategy = routeStrategy; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorHandler() { |
||||
|
return executorHandler; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorHandler(String executorHandler) { |
||||
|
this.executorHandler = executorHandler; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorParam() { |
||||
|
return executorParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorParam(String executorParam) { |
||||
|
this.executorParam = executorParam; |
||||
|
} |
||||
|
|
||||
|
public BlockStrategy getBlockStrategy() { |
||||
|
return blockStrategy; |
||||
|
} |
||||
|
|
||||
|
public void setBlockStrategy(BlockStrategy blockStrategy) { |
||||
|
this.blockStrategy = blockStrategy; |
||||
|
} |
||||
|
|
||||
|
public int getTimeout() { |
||||
|
return timeout; |
||||
|
} |
||||
|
|
||||
|
public void setTimeout(int timeout) { |
||||
|
this.timeout = timeout; |
||||
|
} |
||||
|
|
||||
|
public int getFailRetryCount() { |
||||
|
return failRetryCount; |
||||
|
} |
||||
|
|
||||
|
public void setFailRetryCount(int failRetryCount) { |
||||
|
this.failRetryCount = failRetryCount; |
||||
|
} |
||||
|
|
||||
|
public GlueType getGlueType() { |
||||
|
return glueType; |
||||
|
} |
||||
|
|
||||
|
public void setGlueType(GlueType glueType) { |
||||
|
this.glueType = glueType; |
||||
|
} |
||||
|
|
||||
|
public String getGlueSource() { |
||||
|
return glueSource; |
||||
|
} |
||||
|
|
||||
|
public void setGlueSource(String glueSource) { |
||||
|
this.glueSource = glueSource; |
||||
|
} |
||||
|
|
||||
|
public String getParent() { |
||||
|
return parent; |
||||
|
} |
||||
|
|
||||
|
public void setParent(String parent) { |
||||
|
this.parent = parent; |
||||
|
} |
||||
|
|
||||
|
public TriggerStatus getTriggerStatus() { |
||||
|
return triggerStatus; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerStatus(TriggerStatus triggerStatus) { |
||||
|
this.triggerStatus = triggerStatus; |
||||
|
} |
||||
|
|
||||
|
public long getTriggerLastTime() { |
||||
|
return triggerLastTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerLastTime(long triggerLastTime) { |
||||
|
this.triggerLastTime = triggerLastTime; |
||||
|
} |
||||
|
|
||||
|
public long getTriggerNextTime() { |
||||
|
return triggerNextTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerNextTime(long triggerNextTime) { |
||||
|
this.triggerNextTime = triggerNextTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.entity; |
||||
|
|
||||
|
import io.sc.platform.job.core.vo.ExecutorRegistryVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import javax.validation.constraints.Size; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
@Entity |
||||
|
@Table(name="JOB_EXECUTOR") |
||||
|
public class ExecutorRegistryEntity extends BaseEntity<ExecutorRegistryVo> { |
||||
|
//主键
|
||||
|
@Id |
||||
|
@GeneratedValue(generator = "system-uuid") |
||||
|
@GenericGenerator(name = "system-uuid", strategy = "uuid2") |
||||
|
@Column(name="ID_", length=36) |
||||
|
@Size(max=36) |
||||
|
private String id; |
||||
|
|
||||
|
//名称
|
||||
|
@Column(name="REGISTRY_GROUP_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String registryGroup; |
||||
|
|
||||
|
//名称
|
||||
|
@Column(name="REGISTRY_KEY_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String registryKey; |
||||
|
|
||||
|
//名称
|
||||
|
@Column(name="REGISTRY_VALUE_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String registryValue; |
||||
|
|
||||
|
@Column(name="UPDATE_TIME_") |
||||
|
@Temporal(TemporalType.TIMESTAMP) |
||||
|
private Date updateTime; |
||||
|
|
||||
|
@Override |
||||
|
public ExecutorRegistryVo toVo() { |
||||
|
ExecutorRegistryVo vo =new ExecutorRegistryVo(); |
||||
|
vo.setId(this.getId()); |
||||
|
vo.setRegistryGroup(this.getRegistryGroup()); |
||||
|
vo.setRegistryKey(this.getRegistryKey()); |
||||
|
vo.setRegistryValue(this.getRegistryValue()); |
||||
|
vo.setUpdateTime(this.getUpdateTime()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryGroup() { |
||||
|
return registryGroup; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryGroup(String registryGroup) { |
||||
|
this.registryGroup = registryGroup; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryKey() { |
||||
|
return registryKey; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryKey(String registryKey) { |
||||
|
this.registryKey = registryKey; |
||||
|
} |
||||
|
|
||||
|
public String getRegistryValue() { |
||||
|
return registryValue; |
||||
|
} |
||||
|
|
||||
|
public void setRegistryValue(String registryValue) { |
||||
|
this.registryValue = registryValue; |
||||
|
} |
||||
|
|
||||
|
public Date getUpdateTime() { |
||||
|
return updateTime; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateTime(Date updateTime) { |
||||
|
this.updateTime = updateTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,299 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.entity; |
||||
|
|
||||
|
import io.sc.platform.job.core.enums.*; |
||||
|
import io.sc.platform.job.core.vo.TaskVo; |
||||
|
import io.sc.platform.orm.entity.CorporationAuditorEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import javax.validation.constraints.Size; |
||||
|
|
||||
|
@Entity |
||||
|
@Table(name="JOB_TASK") |
||||
|
public class TaskEntity extends CorporationAuditorEntity<TaskVo> { |
||||
|
//主键
|
||||
|
@Id |
||||
|
@GeneratedValue(generator = "system-uuid") |
||||
|
@GenericGenerator(name = "system-uuid", strategy = "uuid2") |
||||
|
@Column(name="ID_", length=36) |
||||
|
@Size(max=36) |
||||
|
private String id; |
||||
|
|
||||
|
//名称
|
||||
|
@Column(name="NAME_", length=255) |
||||
|
@Size(min=1,max=255) |
||||
|
private String name; |
||||
|
|
||||
|
//描述
|
||||
|
@Column(name="DESCRIPTION_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String description; |
||||
|
|
||||
|
//执行器
|
||||
|
@ManyToOne(fetch= FetchType.LAZY) |
||||
|
@JoinColumn(name="EXECUTOR_ID_") |
||||
|
private ExecutorEntity executor; |
||||
|
|
||||
|
//报警邮件
|
||||
|
@Column(name="ALARM_EMAIL_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String alarmEmail; |
||||
|
|
||||
|
//调度类型
|
||||
|
@Column(name="SCHEDULE_TYPE_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private TaskScheduleType scheduleType; |
||||
|
|
||||
|
//调度配置,值含义取决于调度类型
|
||||
|
@Column(name="SCHEDULE_CONF_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String scheduleConf; |
||||
|
|
||||
|
|
||||
|
//调度过期策略
|
||||
|
@Column(name="EXPIRATION_POLICY_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private ExpirationPolicy expirationPolicy; |
||||
|
|
||||
|
//执行器路由策略
|
||||
|
@Column(name="ROUTE_STRATEGY_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private ExecutorRouteStrategy routeStrategy; |
||||
|
|
||||
|
//执行器,任务Handler名称
|
||||
|
@Column(name="EXECUTOR_HANDLER_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String executorHandler; |
||||
|
|
||||
|
//执行器,任务参数
|
||||
|
@Column(name="EXECUTOR_PARAM_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String executorParam; |
||||
|
|
||||
|
//阻塞处理策略
|
||||
|
@Column(name="BLOCK_STRATEGY_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private BlockStrategy blockStrategy; |
||||
|
|
||||
|
//任务执行超时时间,单位秒
|
||||
|
@Column(name="TIMEOUT_") |
||||
|
private int timeout; |
||||
|
|
||||
|
//失败重试次数
|
||||
|
@Column(name="FAIL_RETRY_COUNT_") |
||||
|
private int failRetryCount; |
||||
|
|
||||
|
//GLUE类型
|
||||
|
@Column(name="GLUE_TYPE_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private GlueType glueType; |
||||
|
|
||||
|
//GLUE源代码
|
||||
|
@Column(name="GLUE_SOURCE_") |
||||
|
private String glueSource; |
||||
|
|
||||
|
//父任务
|
||||
|
@ManyToOne(fetch=FetchType.LAZY) |
||||
|
@JoinColumn(name="PARENT_ID_") |
||||
|
private TaskEntity parent; |
||||
|
|
||||
|
//调度状态
|
||||
|
@Column(name="TRIGGER_STATUS_") |
||||
|
@Enumerated(EnumType.STRING) |
||||
|
private TriggerStatus triggerStatus; |
||||
|
|
||||
|
//上次调度时间
|
||||
|
@Column(name="TRIGGER_LAST_TIME_") |
||||
|
private long triggerLastTime; |
||||
|
|
||||
|
//下次调度时间
|
||||
|
@Column(name="TRIGGER_NEXT_TIME_") |
||||
|
private long triggerNextTime; |
||||
|
|
||||
|
@Override |
||||
|
public TaskVo toVo() { |
||||
|
TaskVo vo =new TaskVo(); |
||||
|
CorporationAuditorEntity.toVo(vo,this); |
||||
|
vo.setId(this.getId()); |
||||
|
vo.setName(this.getName()); |
||||
|
vo.setDescription(this.getDescription()); |
||||
|
vo.setExecutor(this.getExecutor()==null?null:this.getExecutor().getId()); |
||||
|
vo.setAlarmEmail(this.getAlarmEmail()); |
||||
|
vo.setScheduleType(this.getScheduleType()); |
||||
|
vo.setScheduleConf(this.getScheduleConf()); |
||||
|
vo.setExpirationPolicy(this.getExpirationPolicy()); |
||||
|
vo.setRouteStrategy(this.getRouteStrategy()); |
||||
|
vo.setExecutorHandler(this.getExecutorHandler()); |
||||
|
vo.setExecutorParam(this.getExecutorParam()); |
||||
|
vo.setBlockStrategy(this.getBlockStrategy()); |
||||
|
vo.setTimeout(this.getTimeout()); |
||||
|
vo.setFailRetryCount(this.getFailRetryCount()); |
||||
|
vo.setGlueType(this.getGlueType()); |
||||
|
vo.setGlueSource(this.getGlueSource()); |
||||
|
vo.setParent(this.getParent()==null?null:this.getParent().getId()); |
||||
|
vo.setTriggerStatus(this.getTriggerStatus()); |
||||
|
vo.setTriggerLastTime(this.getTriggerLastTime()); |
||||
|
vo.setTriggerNextTime(this.getTriggerNextTime()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getDescription() { |
||||
|
return description; |
||||
|
} |
||||
|
|
||||
|
public void setDescription(String description) { |
||||
|
this.description = description; |
||||
|
} |
||||
|
|
||||
|
public ExecutorEntity getExecutor() { |
||||
|
return executor; |
||||
|
} |
||||
|
|
||||
|
public void setExecutor(ExecutorEntity executor) { |
||||
|
this.executor = executor; |
||||
|
} |
||||
|
|
||||
|
public String getAlarmEmail() { |
||||
|
return alarmEmail; |
||||
|
} |
||||
|
|
||||
|
public void setAlarmEmail(String alarmEmail) { |
||||
|
this.alarmEmail = alarmEmail; |
||||
|
} |
||||
|
|
||||
|
public TaskScheduleType getScheduleType() { |
||||
|
return scheduleType; |
||||
|
} |
||||
|
|
||||
|
public void setScheduleType(TaskScheduleType scheduleType) { |
||||
|
this.scheduleType = scheduleType; |
||||
|
} |
||||
|
|
||||
|
public String getScheduleConf() { |
||||
|
return scheduleConf; |
||||
|
} |
||||
|
|
||||
|
public void setScheduleConf(String scheduleConf) { |
||||
|
this.scheduleConf = scheduleConf; |
||||
|
} |
||||
|
|
||||
|
public ExpirationPolicy getExpirationPolicy() { |
||||
|
return expirationPolicy; |
||||
|
} |
||||
|
|
||||
|
public void setExpirationPolicy(ExpirationPolicy expirationPolicy) { |
||||
|
this.expirationPolicy = expirationPolicy; |
||||
|
} |
||||
|
|
||||
|
public ExecutorRouteStrategy getRouteStrategy() { |
||||
|
return routeStrategy; |
||||
|
} |
||||
|
|
||||
|
public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) { |
||||
|
this.routeStrategy = routeStrategy; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorHandler() { |
||||
|
return executorHandler; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorHandler(String executorHandler) { |
||||
|
this.executorHandler = executorHandler; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorParam() { |
||||
|
return executorParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorParam(String executorParam) { |
||||
|
this.executorParam = executorParam; |
||||
|
} |
||||
|
|
||||
|
public BlockStrategy getBlockStrategy() { |
||||
|
return blockStrategy; |
||||
|
} |
||||
|
|
||||
|
public void setBlockStrategy(BlockStrategy blockStrategy) { |
||||
|
this.blockStrategy = blockStrategy; |
||||
|
} |
||||
|
|
||||
|
public int getTimeout() { |
||||
|
return timeout; |
||||
|
} |
||||
|
|
||||
|
public void setTimeout(int timeout) { |
||||
|
this.timeout = timeout; |
||||
|
} |
||||
|
|
||||
|
public int getFailRetryCount() { |
||||
|
return failRetryCount; |
||||
|
} |
||||
|
|
||||
|
public void setFailRetryCount(int failRetryCount) { |
||||
|
this.failRetryCount = failRetryCount; |
||||
|
} |
||||
|
|
||||
|
public GlueType getGlueType() { |
||||
|
return glueType; |
||||
|
} |
||||
|
|
||||
|
public void setGlueType(GlueType glueType) { |
||||
|
this.glueType = glueType; |
||||
|
} |
||||
|
|
||||
|
public String getGlueSource() { |
||||
|
return glueSource; |
||||
|
} |
||||
|
|
||||
|
public void setGlueSource(String glueSource) { |
||||
|
this.glueSource = glueSource; |
||||
|
} |
||||
|
|
||||
|
public TaskEntity getParent() { |
||||
|
return parent; |
||||
|
} |
||||
|
|
||||
|
public void setParent(TaskEntity parent) { |
||||
|
this.parent = parent; |
||||
|
} |
||||
|
|
||||
|
public TriggerStatus getTriggerStatus() { |
||||
|
return triggerStatus; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerStatus(TriggerStatus triggerStatus) { |
||||
|
this.triggerStatus = triggerStatus; |
||||
|
} |
||||
|
|
||||
|
public long getTriggerLastTime() { |
||||
|
return triggerLastTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerLastTime(long triggerLastTime) { |
||||
|
this.triggerLastTime = triggerLastTime; |
||||
|
} |
||||
|
|
||||
|
public long getTriggerNextTime() { |
||||
|
return triggerNextTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerNextTime(long triggerNextTime) { |
||||
|
this.triggerNextTime = triggerNextTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,230 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.entity; |
||||
|
|
||||
|
import io.sc.platform.job.core.vo.TaskLogVo; |
||||
|
import io.sc.platform.job.core.vo.TaskVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
import io.sc.platform.orm.entity.CorporationAuditorEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import javax.validation.constraints.Size; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
@Entity |
||||
|
@Table(name="JOB_TASK_LOG") |
||||
|
public class TaskLogEntity extends BaseEntity<TaskLogVo> { |
||||
|
//主键
|
||||
|
@Id |
||||
|
@GeneratedValue(generator = "system-uuid") |
||||
|
@GenericGenerator(name = "system-uuid", strategy = "uuid2") |
||||
|
@Column(name="ID_", length=36) |
||||
|
@Size(max=36) |
||||
|
private String id; |
||||
|
|
||||
|
//执行器ID
|
||||
|
@Column(name="EXECUTOR_ID_", length=36) |
||||
|
private String executorId; |
||||
|
|
||||
|
//任务ID
|
||||
|
@Column(name="TASK_ID_", length=36) |
||||
|
private String taskId; |
||||
|
|
||||
|
// execute info
|
||||
|
//执行器地址,本次执行的地址
|
||||
|
@Column(name="EXECUTOR_ADDRESS_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String executorAddress; |
||||
|
|
||||
|
//执行器任务handler
|
||||
|
@Column(name="EXECUTOR_HANDLER_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String executorHandler; |
||||
|
|
||||
|
//执行器任务参数
|
||||
|
@Column(name="EXECUTOR_PARAM_", length=255) |
||||
|
@Size(max=255) |
||||
|
private String executorParam; |
||||
|
|
||||
|
//执行器任务分片参数,格式如 1/2
|
||||
|
@Column(name="EXECUTOR_SHARDING_PARAM_", length=20) |
||||
|
@Size(max=20) |
||||
|
private String executorShardingParam; |
||||
|
|
||||
|
//失败重试次数
|
||||
|
@Column(name="EXECUTOR_FAIL_RETRY_COUNT_") |
||||
|
private int executorFailRetryCount; |
||||
|
|
||||
|
// trigger info
|
||||
|
//调度-时间
|
||||
|
@Column(name="TRIGGER_TIME_") |
||||
|
@Temporal(TemporalType.TIMESTAMP) |
||||
|
private Date triggerTime; |
||||
|
|
||||
|
//调度-结果
|
||||
|
@Column(name="TRIGGER_CODE_") |
||||
|
private int triggerCode; |
||||
|
|
||||
|
//调度-日志
|
||||
|
@Column(name="TRIGGER_MSG_") |
||||
|
private String triggerMsg; |
||||
|
|
||||
|
// handle info
|
||||
|
//执行-时间
|
||||
|
@Column(name="HANDLE_TIME_") |
||||
|
@Temporal(TemporalType.TIMESTAMP) |
||||
|
private Date handleTime; |
||||
|
|
||||
|
//执行-状态
|
||||
|
@Column(name="HANDLE_CODE_") |
||||
|
private int handleCode; |
||||
|
|
||||
|
//执行-日志
|
||||
|
@Column(name="HANDLE_MSG_") |
||||
|
private String handleMsg; |
||||
|
|
||||
|
// alarm info
|
||||
|
//告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败
|
||||
|
@Column(name="ALARM_STATUS_") |
||||
|
private int alarmStatus; |
||||
|
|
||||
|
@Override |
||||
|
public TaskLogVo toVo() { |
||||
|
TaskLogVo vo =new TaskLogVo(); |
||||
|
vo.setId(this.getId()); |
||||
|
vo.setExecutorId(this.getExecutorId()); |
||||
|
vo.setTaskId(this.getTaskId()); |
||||
|
vo.setExecutorAddress(this.getExecutorAddress()); |
||||
|
vo.setExecutorHandler(this.getExecutorHandler()); |
||||
|
vo.setExecutorParam(this.getExecutorParam()); |
||||
|
vo.setExecutorShardingParam(this.getExecutorShardingParam()); |
||||
|
vo.setExecutorFailRetryCount(this.getExecutorFailRetryCount()); |
||||
|
vo.setTriggerTime(this.getTriggerTime()); |
||||
|
vo.setTriggerCode(this.getTriggerCode()); |
||||
|
vo.setTriggerMsg(this.getTriggerMsg()); |
||||
|
vo.setHandleTime(this.getHandleTime()); |
||||
|
vo.setHandleCode(this.getHandleCode()); |
||||
|
vo.setHandleMsg(this.getHandleMsg()); |
||||
|
vo.setAlarmStatus(this.getAlarmStatus()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorId() { |
||||
|
return executorId; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorId(String executorId) { |
||||
|
this.executorId = executorId; |
||||
|
} |
||||
|
|
||||
|
public String getTaskId() { |
||||
|
return taskId; |
||||
|
} |
||||
|
|
||||
|
public void setTaskId(String taskId) { |
||||
|
this.taskId = taskId; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorAddress() { |
||||
|
return executorAddress; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorAddress(String executorAddress) { |
||||
|
this.executorAddress = executorAddress; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorHandler() { |
||||
|
return executorHandler; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorHandler(String executorHandler) { |
||||
|
this.executorHandler = executorHandler; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorParam() { |
||||
|
return executorParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorParam(String executorParam) { |
||||
|
this.executorParam = executorParam; |
||||
|
} |
||||
|
|
||||
|
public String getExecutorShardingParam() { |
||||
|
return executorShardingParam; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorShardingParam(String executorShardingParam) { |
||||
|
this.executorShardingParam = executorShardingParam; |
||||
|
} |
||||
|
|
||||
|
public int getExecutorFailRetryCount() { |
||||
|
return executorFailRetryCount; |
||||
|
} |
||||
|
|
||||
|
public void setExecutorFailRetryCount(int executorFailRetryCount) { |
||||
|
this.executorFailRetryCount = executorFailRetryCount; |
||||
|
} |
||||
|
|
||||
|
public Date getTriggerTime() { |
||||
|
return triggerTime; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerTime(Date triggerTime) { |
||||
|
this.triggerTime = triggerTime; |
||||
|
} |
||||
|
|
||||
|
public int getTriggerCode() { |
||||
|
return triggerCode; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerCode(int triggerCode) { |
||||
|
this.triggerCode = triggerCode; |
||||
|
} |
||||
|
|
||||
|
public String getTriggerMsg() { |
||||
|
return triggerMsg; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerMsg(String triggerMsg) { |
||||
|
this.triggerMsg = triggerMsg; |
||||
|
} |
||||
|
|
||||
|
public Date getHandleTime() { |
||||
|
return handleTime; |
||||
|
} |
||||
|
|
||||
|
public void setHandleTime(Date handleTime) { |
||||
|
this.handleTime = handleTime; |
||||
|
} |
||||
|
|
||||
|
public int getHandleCode() { |
||||
|
return handleCode; |
||||
|
} |
||||
|
|
||||
|
public void setHandleCode(int handleCode) { |
||||
|
this.handleCode = handleCode; |
||||
|
} |
||||
|
|
||||
|
public String getHandleMsg() { |
||||
|
return handleMsg; |
||||
|
} |
||||
|
|
||||
|
public void setHandleMsg(String handleMsg) { |
||||
|
this.handleMsg = handleMsg; |
||||
|
} |
||||
|
|
||||
|
public int getAlarmStatus() { |
||||
|
return alarmStatus; |
||||
|
} |
||||
|
|
||||
|
public void setAlarmStatus(int alarmStatus) { |
||||
|
this.alarmStatus = alarmStatus; |
||||
|
} |
||||
|
} |
@ -0,0 +1,99 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.entity; |
||||
|
|
||||
|
import io.sc.platform.job.core.vo.TaskLogReportVo; |
||||
|
import io.sc.platform.job.core.vo.TaskLogVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import javax.validation.constraints.Size; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
@Entity |
||||
|
@Table(name="JOB_TASK_LOG_REPORT") |
||||
|
public class TaskLogReportEntity extends BaseEntity<TaskLogReportVo> { |
||||
|
//主键
|
||||
|
@Id |
||||
|
@GeneratedValue(generator = "system-uuid") |
||||
|
@GenericGenerator(name = "system-uuid", strategy = "uuid2") |
||||
|
@Column(name="ID_", length=36) |
||||
|
@Size(max=36) |
||||
|
private String id; |
||||
|
|
||||
|
@Column(name="TRIGGER_DAY_") |
||||
|
@Temporal(TemporalType.TIMESTAMP) |
||||
|
private Date triggerDay; |
||||
|
|
||||
|
@Column(name="RUNNING_COUNT_") |
||||
|
private int runningCount; |
||||
|
|
||||
|
@Column(name="SUC_COUNT_") |
||||
|
private int sucCount; |
||||
|
|
||||
|
@Column(name="FAIL_COUNT_") |
||||
|
private int failCount; |
||||
|
|
||||
|
@Column(name="UPDATE_TIME_") |
||||
|
@Temporal(TemporalType.TIMESTAMP) |
||||
|
private Date updateTime; |
||||
|
|
||||
|
@Override |
||||
|
public TaskLogReportVo toVo() { |
||||
|
TaskLogReportVo vo =new TaskLogReportVo(); |
||||
|
vo.setId(this.getId()); |
||||
|
vo.setTriggerDay(this.getTriggerDay()); |
||||
|
vo.setRunningCount(this.getRunningCount()); |
||||
|
vo.setSucCount(this.getSucCount()); |
||||
|
vo.setFailCount(this.getFailCount()); |
||||
|
vo.setUpdateTime(this.getUpdateTime()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public Date getTriggerDay() { |
||||
|
return triggerDay; |
||||
|
} |
||||
|
|
||||
|
public void setTriggerDay(Date triggerDay) { |
||||
|
this.triggerDay = triggerDay; |
||||
|
} |
||||
|
|
||||
|
public int getRunningCount() { |
||||
|
return runningCount; |
||||
|
} |
||||
|
|
||||
|
public void setRunningCount(int runningCount) { |
||||
|
this.runningCount = runningCount; |
||||
|
} |
||||
|
|
||||
|
public int getSucCount() { |
||||
|
return sucCount; |
||||
|
} |
||||
|
|
||||
|
public void setSucCount(int sucCount) { |
||||
|
this.sucCount = sucCount; |
||||
|
} |
||||
|
|
||||
|
public int getFailCount() { |
||||
|
return failCount; |
||||
|
} |
||||
|
|
||||
|
public void setFailCount(int failCount) { |
||||
|
this.failCount = failCount; |
||||
|
} |
||||
|
|
||||
|
public Date getUpdateTime() { |
||||
|
return updateTime; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateTime(Date updateTime) { |
||||
|
this.updateTime = updateTime; |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.repository; |
||||
|
|
||||
|
import io.sc.platform.job.core.enums.ExecutorAddressType; |
||||
|
import io.sc.platform.job.manager.jpa.entity.ExecutorEntity; |
||||
|
import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.repository.query.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface ExecutorRegistryRepository extends DaoRepository<ExecutorRegistryEntity,String> { |
||||
|
} |
@ -1,12 +1,12 @@ |
|||||
package io.sc.platform.job.manager.jpa.repository; |
package io.sc.platform.job.manager.jpa.repository; |
||||
|
|
||||
import io.sc.platform.job.core.enums.ExecutorAddressType; |
import io.sc.platform.job.core.enums.ExecutorAddressType; |
||||
import io.sc.platform.job.manager.jpa.entity.JobGroupEntity; |
import io.sc.platform.job.manager.jpa.entity.ExecutorEntity; |
||||
import io.sc.platform.orm.repository.DaoRepository; |
import io.sc.platform.orm.repository.DaoRepository; |
||||
import org.springframework.data.repository.query.Param; |
import org.springframework.data.repository.query.Param; |
||||
|
|
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
public interface JobGroupRepository extends DaoRepository<JobGroupEntity,String> { |
public interface ExecutorRepository extends DaoRepository<ExecutorEntity,String> { |
||||
public List<JobGroupEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType); |
public List<ExecutorEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType); |
||||
} |
} |
@ -0,0 +1,8 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.repository; |
||||
|
|
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskLogEntity; |
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskLogReportEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
|
||||
|
public interface TaskLogReportRepository extends DaoRepository<TaskLogReportEntity,String> { |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.repository; |
||||
|
|
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskLogEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
|
||||
|
public interface TaskLogRepository extends DaoRepository<TaskLogEntity,String> { |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
package io.sc.platform.job.manager.jpa.repository; |
||||
|
|
||||
|
import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity; |
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
|
||||
|
public interface TaskRepository extends DaoRepository<TaskEntity,String> { |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
package io.sc.platform.job.manager.service; |
||||
|
|
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskEntity; |
||||
|
import io.sc.platform.job.manager.jpa.repository.TaskRepository; |
||||
|
import io.sc.platform.orm.service.DaoService; |
||||
|
|
||||
|
public interface TaskService extends DaoService<TaskEntity, String, TaskRepository> { |
||||
|
public void start(int id); |
||||
|
public void stop(int id); |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
package io.sc.platform.job.manager.service.impl; |
||||
|
|
||||
|
import io.sc.platform.job.core.enums.TaskScheduleType; |
||||
|
import io.sc.platform.job.manager.jpa.entity.TaskEntity; |
||||
|
import io.sc.platform.job.manager.jpa.repository.TaskRepository; |
||||
|
import io.sc.platform.job.manager.service.TaskService; |
||||
|
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class TaskServiceImpl extends DaoServiceImpl<TaskEntity, String, TaskRepository> implements TaskService { |
||||
|
@Override |
||||
|
public void start(String id) { |
||||
|
TaskEntity taskEntity =this.findById(id); |
||||
|
if(taskEntity==null){ |
||||
|
return; |
||||
|
} |
||||
|
if(TaskScheduleType.NONE.equals(taskEntity.getScheduleType())){ |
||||
|
throw new RuntimeException(); |
||||
|
} |
||||
|
long nextTriggerTime = 0; |
||||
|
|
||||
|
|
||||
|
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); |
||||
|
|
||||
|
// valid
|
||||
|
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE); |
||||
|
if (ScheduleTypeEnum.NONE == scheduleTypeEnum) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")) ); |
||||
|
} |
||||
|
|
||||
|
// next trigger time (5s后生效,避开预读周期)
|
||||
|
long nextTriggerTime = 0; |
||||
|
try { |
||||
|
Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); |
||||
|
if (nextValidTime == null) { |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); |
||||
|
} |
||||
|
nextTriggerTime = nextValidTime.getTime(); |
||||
|
} catch (Exception e) { |
||||
|
logger.error(e.getMessage(), e); |
||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); |
||||
|
} |
||||
|
|
||||
|
xxlJobInfo.setTriggerStatus(1); |
||||
|
xxlJobInfo.setTriggerLastTime(0); |
||||
|
xxlJobInfo.setTriggerNextTime(nextTriggerTime); |
||||
|
|
||||
|
xxlJobInfo.setUpdateTime(new Date()); |
||||
|
xxlJobInfoDao.update(xxlJobInfo); |
||||
|
return ReturnT.SUCCESS; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void stop(int id) { |
||||
|
|
||||
|
} |
||||
|
} |
Loading…
Reference in new issue