Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
X
XXL-JOB
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
靳帅
XXL-JOB
Commits
7e350887
提交
7e350887
authored
6月 27, 2017
作者:
xuxueli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
路由策略新增 "忙碌转移" 模式:按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
上级
1ad6950e
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
95 行增加
和
62 行删除
+95
-62
README.md
README.md
+2
-1
RemoteHttpJobBean.java
...ava/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java
+65
-59
ExecutorRouteStrategyEnum.java
...m/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java
+2
-1
ExecutorBiz.java
...-core/src/main/java/com/xxl/job/core/biz/ExecutorBiz.java
+8
-0
ExecutorBizImpl.java
.../main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java
+16
-0
ExecutorRegistryThread.java
.../java/com/xxl/job/core/thread/ExecutorRegistryThread.java
+2
-1
没有找到文件。
README.md
浏览文件 @
7e350887
...
...
@@ -857,6 +857,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
-
1、任务Cron更新逻辑优化,改为rescheduleJob,同时防止cron重复设置;
-
2、优化:API回调服务失败状态码优化,方便问题排查;
-
3、XxlJobLogger的日志多参数支持;
-
4、路由策略新增 "忙碌转移" 模式:按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
#### TODO LIST
-
1、任务权限管理:执行器为粒度分配权限,核心操作校验权限;
...
...
@@ -868,7 +869,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
-
7、调度任务优先级;
-
8、移除quartz依赖,重写调度模块:新增或恢复任务时将下次执行记录插入delayqueue,调度中心集群竞争分布式锁,成功节点批量加载到期delayqueue数据,批量执行。
-
9、任务线程轮空30次后自动销毁,降低低频任务的无效线程消耗。
-
10、路由策略新增 "忙碌转移" 模式,发现执行器运行中,主动转移下一个执行器调度任务;
## 七、其他
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java
浏览文件 @
7e350887
...
...
@@ -114,76 +114,82 @@ public class RemoteHttpJobBean extends QuartzJobBean {
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
//
trigger remote executor
if
(
addressList
.
size
()
==
1
)
{
String
address
=
addressList
.
get
(
0
);
jobLog
.
setExecutorAddress
(
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
//
executor route strategy
ExecutorRouteStrategyEnum
executorRouteStrategyEnum
=
ExecutorRouteStrategyEnum
.
match
(
jobInfo
.
getExecutorRouteStrategy
(),
null
);
if
(
executorRouteStrategyEnum
==
null
)
{
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
"调度失败:"
).
append
(
"执行器路由策略为空"
);
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
triggerSb
.
append
(
"<br>路由策略:"
).
append
(
executorRouteStrategyEnum
.
name
()
+
"-"
+
executorRouteStrategyEnum
.
getTitle
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
else
{
// executor route strategy
ExecutorRouteStrategyEnum
executorRouteStrategyEnum
=
ExecutorRouteStrategyEnum
.
match
(
jobInfo
.
getExecutorRouteStrategy
(),
null
);
triggerSb
.
append
(
"<br>路由策略:"
).
append
(
executorRouteStrategyEnum
!=
null
?(
executorRouteStrategyEnum
.
name
()
+
"-"
+
executorRouteStrategyEnum
.
getTitle
()):
null
);
if
(
executorRouteStrategyEnum
==
null
)
{
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
"调度失败:"
).
append
(
"执行器路由策略为空"
);
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
// trigger remote executor
if
(
executorRouteStrategyEnum
==
ExecutorRouteStrategyEnum
.
FAILOVER
)
{
for
(
String
address
:
addressList
)
{
// beat
ReturnT
<
String
>
beatResult
=
null
;
try
{
ExecutorBiz
executorBiz
=
(
ExecutorBiz
)
new
NetComClientProxy
(
ExecutorBiz
.
class
,
address
).
getObject
();
beatResult
=
executorBiz
.
beat
();
}
catch
(
Exception
e
)
{
logger
.
error
(
""
,
e
);
beatResult
=
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
""
+
e
);
}
triggerSb
.
append
(
"<br>----------------------<br>"
)
.
append
(
"心跳检测:"
)
.
append
(
"<br>address:"
).
append
(
address
)
.
append
(
"<br>code:"
).
append
(
beatResult
.
getCode
())
.
append
(
"<br>msg:"
).
append
(
beatResult
.
getMsg
());
if
(
executorRouteStrategyEnum
!=
ExecutorRouteStrategyEnum
.
FAILOVER
)
{
// get address
String
address
=
executorRouteStrategyEnum
.
getRouter
().
route
(
jobInfo
.
getId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
// beat success
if
(
beatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
jobLog
.
setExecutorAddress
(
address
);
// run
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
else
{
for
(
String
address
:
addressList
)
{
// beat
ReturnT
<
String
>
beatResult
=
beatExecutor
(
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
beatResult
.
getMsg
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
}
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
else
if
(
executorRouteStrategyEnum
==
ExecutorRouteStrategyEnum
.
BUSYOVER
)
{
for
(
String
address
:
addressList
)
{
// beat
ReturnT
<
String
>
idleBeatResult
=
null
;
try
{
ExecutorBiz
executorBiz
=
(
ExecutorBiz
)
new
NetComClientProxy
(
ExecutorBiz
.
class
,
address
).
getObject
();
idleBeatResult
=
executorBiz
.
idleBeat
(
triggerParam
.
getJobId
());
}
catch
(
Exception
e
)
{
logger
.
error
(
""
,
e
);
idleBeatResult
=
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
""
+
e
);
}
triggerSb
.
append
(
"<br>----------------------<br>"
)
.
append
(
"空闲检测:"
)
.
append
(
"<br>address:"
).
append
(
address
)
.
append
(
"<br>code:"
).
append
(
idleBeatResult
.
getCode
())
.
append
(
"<br>msg:"
).
append
(
idleBeatResult
.
getMsg
());
if
(
beatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
jobLog
.
setExecutorAddress
(
address
);
// beat success
if
(
idleBeatResult
.
getCode
()
==
ReturnT
.
SUCCESS_CODE
)
{
jobLog
.
setExecutorAddress
(
address
);
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
}
}
/**
* run executor
* @param address
* @return
*/
public
ReturnT
<
String
>
beatExecutor
(
String
address
){
ReturnT
<
String
>
beatResult
=
null
;
try
{
ExecutorBiz
executorBiz
=
(
ExecutorBiz
)
new
NetComClientProxy
(
ExecutorBiz
.
class
,
address
).
getObject
();
beatResult
=
executorBiz
.
beat
();
}
catch
(
Exception
e
)
{
logger
.
error
(
""
,
e
);
beatResult
=
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
""
+
e
);
}
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
triggerSb
.
toString
());
}
else
{
// get address
String
address
=
executorRouteStrategyEnum
.
getRouter
().
route
(
jobInfo
.
getId
(),
addressList
);
jobLog
.
setExecutorAddress
(
address
);
StringBuffer
sb
=
new
StringBuffer
(
"心跳检测:"
);
sb
.
append
(
"<br>address:"
).
append
(
address
);
sb
.
append
(
"<br>code:"
).
append
(
beatResult
.
getCode
());
sb
.
append
(
"<br>msg:"
).
append
(
beatResult
.
getMsg
());
beatResult
.
setMsg
(
sb
.
toString
());
// run
ReturnT
<
String
>
runResult
=
runExecutor
(
triggerParam
,
address
);
triggerSb
.
append
(
"<br>----------------------<br>"
).
append
(
runResult
.
getMsg
());
return
beatResult
;
return
new
ReturnT
<
String
>(
runResult
.
getCode
(),
triggerSb
.
toString
());
}
}
/**
...
...
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java
浏览文件 @
7e350887
...
...
@@ -14,7 +14,8 @@ public enum ExecutorRouteStrategyEnum {
CONSISTENT_HASH
(
"一致性HASH"
,
new
ExecutorRouteConsistentHash
()),
LEAST_FREQUENTLY_USED
(
"最不经常使用"
,
new
ExecutorRouteLFU
()),
LEAST_RECENTLY_USED
(
"最近最久未使用"
,
new
ExecutorRouteLRU
()),
FAILOVER
(
"故障转移"
,
null
);
FAILOVER
(
"故障转移"
,
null
),
BUSYOVER
(
"忙碌转移"
,
null
);
ExecutorRouteStrategyEnum
(
String
title
,
ExecutorRouter
router
)
{
this
.
title
=
title
;
...
...
xxl-job-core/src/main/java/com/xxl/job/core/biz/ExecutorBiz.java
浏览文件 @
7e350887
...
...
@@ -15,6 +15,14 @@ public interface ExecutorBiz {
*/
public
ReturnT
<
String
>
beat
();
/**
* idle beat
*
* @param jobId
* @return
*/
public
ReturnT
<
String
>
idleBeat
(
int
jobId
);
/**
* kill
* @param jobId
...
...
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java
浏览文件 @
7e350887
...
...
@@ -29,6 +29,22 @@ public class ExecutorBizImpl implements ExecutorBiz {
return
ReturnT
.
SUCCESS
;
}
@Override
public
ReturnT
<
String
>
idleBeat
(
int
jobId
)
{
// isRunningOrHasQueue
boolean
isRunningOrHasQueue
=
false
;
JobThread
jobThread
=
XxlJobExecutor
.
loadJobThread
(
jobId
);
if
(
jobThread
!=
null
&&
jobThread
.
isRunningOrHasQueue
())
{
isRunningOrHasQueue
=
true
;
}
if
(
isRunningOrHasQueue
)
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
"job thread is running or has trigger queue."
);
}
return
ReturnT
.
SUCCESS
;
}
@Override
public
ReturnT
<
String
>
kill
(
int
jobId
)
{
// kill handlerThread, and create new one
...
...
xxl-job-core/src/main/java/com/xxl/job/core/thread/ExecutorRegistryThread.java
浏览文件 @
7e350887
...
...
@@ -46,7 +46,8 @@ public class ExecutorRegistryThread extends Thread {
try
{
RegistryParam
registryParam
=
new
RegistryParam
(
RegistryConfig
.
RegistType
.
EXECUTOR
.
name
(),
appName
,
executorAddress
);
ReturnT
<
String
>
registryResult
=
AdminApiUtil
.
callApiFailover
(
AdminApiUtil
.
REGISTRY
,
registryParam
);
logger
.
info
(
">>>>>>>>>>> xxl-job registry, RegistryParam:{}, registryResult:{}"
,
new
Object
[]{
registryParam
.
toString
(),
registryResult
.
toString
()});
logger
.
info
(
">>>>>>>>>>> xxl-job Executor registry {}, RegistryParam:{}, registryResult:{}"
,
new
Object
[]{(
registryResult
.
getCode
()==
ReturnT
.
SUCCESS_CODE
?
"success"
:
"fail"
),
registryParam
.
toString
(),
registryResult
.
toString
()});
}
catch
(
Exception
e
)
{
logger
.
error
(
">>>>>>>>>>> xxl-job ExecutorRegistryThread Exception:"
,
e
);
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论