先上总结:
- 可以disable job或者server,或者某个server上的job实例
- 还是会定时调度,但调度过程发现为disable后不运行job
disable 入口代码:
private void disableOrEnableJobs(final Optional<String> jobName, final Optional<String> serverIp, final boolean disabled) {
Preconditions.checkArgument(jobName.isPresent() || serverIp.isPresent(), "At least indicate jobName or serverIp.");
if (jobName.isPresent() && serverIp.isPresent()) {
persistDisabledOrEnabledJob(jobName.get(), serverIp.get(), disabled);
} else if (jobName.isPresent()) {
JobNodePath jobNodePath = new JobNodePath(jobName.get());
for (String each : regCenter.getChildrenKeys(jobNodePath.getServerNodePath())) {
if (disabled) {
regCenter.persist(jobNodePath.getServerNodePath(each), "DISABLED");
} else {
regCenter.persist(jobNodePath.getServerNodePath(each), "");
}
}
} else if (serverIp.isPresent()) {
List<String> jobNames = regCenter.getChildrenKeys("/");
for (String each : jobNames) {
if (regCenter.isExisted(new JobNodePath(each).getServerNodePath(serverIp.get()))) {
persistDisabledOrEnabledJob(each, serverIp.get(), disabled);
}
}
}
}
disable的nodepath 为 /test-disablejobName/servers/192.168.157.1,即按server 进行disable
JOB调度执行函数为类AbstractElasticJobExecutor的如下代码:
private void execute(final ShardingContexts shardingContexts, final JobExecutionEvent.ExecutionSource executionSource) {
if (shardingContexts.getShardingItemParameters().isEmpty()) {
if (shardingContexts.isAllowSendJobEvent()) {
jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), State.TASK_FINISHED, String.format("Sharding item for job '%s' is empty.", jobName));
}
return;
}
上面代码的getShardingItemParameters 会返回empty,shardingContexts的获取来自以下代码:
@Override
public ShardingContexts getShardingContexts() {
boolean isFailover = configService.load(true).isFailover();
if (isFailover) {
List<Integer> failoverShardingItems = failoverService.getLocalFailoverItems();
if (!failoverShardingItems.isEmpty()) {
return executionContextService.getJobShardingContext(failoverShardingItems);
}
}
shardingService.shardingIfNecessary();
List<Integer> shardingItems = shardingService.getLocalShardingItems();
if (isFailover) {
shardingItems.removeAll(failoverService.getLocalTakeOffItems());
}
shardingItems.removeAll(executionService.getDisabledItems(shardingItems));
return executionContextService.getJobShardingContext(shardingItems);
}
而关键的获取getLocalShardingItems,本地sharding item的相关代码如下:
/**
* 获取运行在本作业实例的分片项集合.
*
* @return 运行在本作业实例的分片项集合
*/
public List<Integer> getLocalShardingItems() {
if (JobRegistry.getInstance().isShutdown(jobName) || !serverService.isAvailableServer(JobRegistry.getInstance().getJobInstance(jobName).getIp())) {
return Collections.emptyList();
}
return getShardingItems(JobRegistry.getInstance().getJobInstance(jobName).getJobInstanceId());
}
/**
* 判断作业服务器是否可用.
*
* @param ip 作业服务器IP地址
* @return 作业服务器是否可用
*/
public boolean isAvailableServer(final String ip) {
return isEnableServer(ip) && hasOnlineInstances(ip);
}
private boolean hasOnlineInstances(final String ip) {
for (String each : jobNodeStorage.getJobNodeChildrenKeys(InstanceNode.ROOT)) {
if (each.startsWith(ip)) {
return true;
}
}
return false;
}
/**
* 判断服务器是否启用.
*
* @param ip 作业服务器IP地址
* @return 服务器是否启用
*/
public boolean isEnableServer(final String ip) {
return !ServerStatus.DISABLED.name().equals(jobNodeStorage.getJobNodeData(serverNode.getServerNode(ip)));
}
注意以上的hasOnlineInstances函数及isEnableServer,去zookeeper获取的相关path里面的状态被disabled。