|
|
@@ -49,19 +49,20 @@ public class MultiScopeJobDispatcher {
|
|
|
@Value("${saas.task.parallel.threads:4}") private int parallelThreads;
|
|
|
private volatile ExecutorService tenantExecutor;
|
|
|
|
|
|
- public void dispatch(JobExecutionContext context, SysJob sysJob, ScopedJobExecutor executor) throws Exception {
|
|
|
+ public boolean dispatch(JobExecutionContext context, SysJob sysJob, ScopedJobExecutor executor) throws Exception {
|
|
|
if (!JobInvokeUtil.isInvokeTargetAvailable(sysJob)) {
|
|
|
log.warn("[MultiScopeJob] invokeTarget 在当前进程不可用,跳过执行: jobName={}, invokeTarget={}, jobGroup={}",
|
|
|
sysJob.getJobName(), sysJob.getInvokeTarget(), sysJob.getJobGroup());
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
String scope = resolveScope(sysJob);
|
|
|
if (ScheduleConstants.JobScope.TENANT.getValue().equals(scope)) {
|
|
|
log.info("[MultiScopeJob] 租户级任务: jobName={}, templateId={}", sysJob.getJobName(), sysJob.getJobId());
|
|
|
- executeTenantJob(context, sysJob, executor);
|
|
|
+ return executeTenantJob(context, sysJob, executor);
|
|
|
} else {
|
|
|
log.debug("[MultiScopeJob] 平台级任务: jobName={}", sysJob.getJobName());
|
|
|
executePlatformJob(context, sysJob, executor);
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -103,19 +104,40 @@ public class MultiScopeJobDispatcher {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void executeTenantJob(JobExecutionContext context, SysJob sysJob, ScopedJobExecutor executor) throws Exception {
|
|
|
+ private boolean executeTenantJob(JobExecutionContext context, SysJob sysJob, ScopedJobExecutor executor) throws Exception {
|
|
|
List<TenantJobConfig> tenantConfigs = queryAssignedTenants(sysJob);
|
|
|
if (tenantConfigs.isEmpty()) {
|
|
|
log.warn("[MultiScopeJob] 租户级任务未分配任何租户: jobName={}, templateId={}",
|
|
|
sysJob.getJobName(), sysJob.getJobId());
|
|
|
- return;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关键优化:过滤掉已暂停的租户配置
|
|
|
+ List<TenantJobConfig> enabledConfigs = tenantConfigs.stream()
|
|
|
+ .filter(config -> "0".equals(config.getStatus()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<Long> pausedTenantIds = tenantConfigs.stream()
|
|
|
+ .filter(config -> !"0".equals(config.getStatus()))
|
|
|
+ .map(TenantJobConfig::getTenantId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!pausedTenantIds.isEmpty()) {
|
|
|
+ log.info("[MultiScopeJob] 跳过已暂停的租户: jobName={}, tenantIds={}",
|
|
|
+ sysJob.getJobName(), pausedTenantIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (enabledConfigs.isEmpty()) {
|
|
|
+ log.warn("[MultiScopeJob] 所有租户配置均已暂停: jobName={}, templateId={}",
|
|
|
+ sysJob.getJobName(), sysJob.getJobId());
|
|
|
+ return false;
|
|
|
}
|
|
|
- log.info("[MultiScopeJob] 开始并行执行租户任务: jobName={}, templateId={}, 租户数={}, tenantIds={}",
|
|
|
- sysJob.getJobName(), sysJob.getJobId(), tenantConfigs.size(),
|
|
|
- tenantConfigs.stream().map(TenantJobConfig::getTenantId).collect(Collectors.toList()));
|
|
|
- CountDownLatch latch = new CountDownLatch(tenantConfigs.size());
|
|
|
+
|
|
|
+ log.info("[MultiScopeJob] 开始并行执行租户任务: jobName={}, templateId={}, 总租户数={}, 启用租户数={}",
|
|
|
+ sysJob.getJobName(), sysJob.getJobId(), tenantConfigs.size(), enabledConfigs.size());
|
|
|
+ CountDownLatch latch = new CountDownLatch(enabledConfigs.size());
|
|
|
AtomicInteger failCount = new AtomicInteger(0);
|
|
|
- for (TenantJobConfig config : tenantConfigs) {
|
|
|
+ for (TenantJobConfig config : enabledConfigs) {
|
|
|
getTenantExecutor().submit(() -> {
|
|
|
if (executeForOneTenant(context, sysJob, config, executor)) failCount.incrementAndGet();
|
|
|
latch.countDown();
|
|
|
@@ -132,18 +154,26 @@ public class MultiScopeJobDispatcher {
|
|
|
if (failCount.get() > 0) {
|
|
|
throw new IllegalStateException("租户任务部分失败: jobName=" + sysJob.getJobId() + ", 失败数=" + failCount.get());
|
|
|
}
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
private List<TenantJobConfig> queryAssignedTenants(SysJob sysJob) {
|
|
|
try {
|
|
|
DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
|
|
|
Long templateId = resolveTemplateId(sysJob);
|
|
|
+ Long jobId = sysJob.getJobId();
|
|
|
+ log.info("[MultiScopeJob] 查询租户配置: jobId={}, resolvedTemplateId={}, jobName={}",
|
|
|
+ jobId, templateId, sysJob.getJobName());
|
|
|
if (templateId == null) {
|
|
|
log.warn("[MultiScopeJob] 无法解析 templateId,跳过租户分发: jobName={}, jobId={}",
|
|
|
- sysJob.getJobName(), sysJob.getJobId());
|
|
|
+ sysJob.getJobName(), jobId);
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
List<TenantJobConfig> list = tenantJobConfigMapper.selectTenantsByTemplateId(templateId);
|
|
|
+ int enabledCount = list != null ? (int) list.stream().filter(c -> "0".equals(c.getStatus())).count() : 0;
|
|
|
+ int pausedCount = list != null ? (int) list.stream().filter(c -> !"0".equals(c.getStatus())).count() : 0;
|
|
|
+ log.info("[MultiScopeJob] 查询结果: templateId={}, 总数={}, 启用={}, 暂停={}",
|
|
|
+ templateId, list != null ? list.size() : 0, enabledCount, pausedCount);
|
|
|
return list != null ? list : Collections.emptyList();
|
|
|
} finally {
|
|
|
DynamicDataSourceContextHolder.clearDataSourceType();
|