Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
熊鹏飞
/
xxljob220
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
7e350887
authored
Jun 27, 2017
by
xuxueli
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
路由策略新增 "忙碌转移" 模式:按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
parent
1ad6950e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
95 additions
and
62 deletions
README.md
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java
xxl-job-core/src/main/java/com/xxl/job/core/biz/ExecutorBiz.java
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java
xxl-job-core/src/main/java/com/xxl/job/core/thread/ExecutorRegistryThread.java
README.md
View file @
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
View file @
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
View file @
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
View file @
7e350887
...
...
@@ -16,6 +16,14 @@ public interface ExecutorBiz {
public
ReturnT
<
String
>
beat
();
/**
* idle beat
*
* @param jobId
* @return
*/
public
ReturnT
<
String
>
idleBeat
(
int
jobId
);
/**
* kill
* @param jobId
* @return
...
...
xxl-job-core/src/main/java/com/xxl/job/core/biz/impl/ExecutorBizImpl.java
View file @
7e350887
...
...
@@ -30,6 +30,22 @@ public class ExecutorBizImpl implements ExecutorBiz {
}
@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
JobThread
jobThread
=
XxlJobExecutor
.
loadJobThread
(
jobId
);
...
...
xxl-job-core/src/main/java/com/xxl/job/core/thread/ExecutorRegistryThread.java
View file @
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
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment