com.github.ltsopensource.spring.quartz.QuartzLTSProxyAgent Maven / Gradle / Ivy
The newest version!
package com.github.ltsopensource.spring.quartz;
import com.github.ltsopensource.core.commons.utils.CollectionUtils;
import com.github.ltsopensource.core.commons.utils.QuietUtils;
import com.github.ltsopensource.core.domain.Job;
import com.github.ltsopensource.core.factory.NamedThreadFactory;
import com.github.ltsopensource.core.json.JSON;
import com.github.ltsopensource.core.logger.Logger;
import com.github.ltsopensource.core.logger.LoggerFactory;
import com.github.ltsopensource.jobclient.JobClient;
import com.github.ltsopensource.jobclient.JobClientBuilder;
import com.github.ltsopensource.core.properties.JobClientProperties;
import com.github.ltsopensource.jobclient.domain.Response;
import com.github.ltsopensource.tasktracker.TaskTracker;
import com.github.ltsopensource.tasktracker.TaskTrackerBuilder;
import com.github.ltsopensource.tasktracker.runner.JobRunner;
import com.github.ltsopensource.tasktracker.runner.RunnerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Robert HG ([email protected]) on 3/16/16.
*/
class QuartzLTSProxyAgent {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzLTSProxyAgent.class);
private QuartzLTSConfig quartzLTSConfig;
private List quartzJobContexts = new CopyOnWriteArrayList();
private AtomicBoolean ready = new AtomicBoolean(false);
public QuartzLTSProxyAgent(QuartzLTSConfig quartzLTSConfig) {
this.quartzLTSConfig = quartzLTSConfig;
}
// 开始代理
public void startProxy(List cronJobs) {
if (CollectionUtils.isEmpty(cronJobs)) {
return;
}
quartzJobContexts.addAll(cronJobs);
if (!ready.compareAndSet(false, true)) {
return;
}
new NamedThreadFactory(QuartzLTSProxyAgent.class.getSimpleName() + "_LazyStart").newThread(new Runnable() {
@Override
public void run() {
try {
// 3S之后启动 JobClient和TaskTracker, 为了防止有多个SchedulerFactoryBean, 从而这个方法被调用多次
QuietUtils.sleep(3000);
startProxy0();
} catch (Throwable t) {
LOGGER.error("Error on start " + QuartzLTSProxyAgent.class.getSimpleName(), t);
}
}
}).start();
}
private void startProxy0() {
// 1. 先启动 TaskTracker
startTaskTracker();
// 2. 启动JobClient并提交任务
JobClient jobClient = startJobClient();
// 3. 提交任务
submitJobs(jobClient);
}
private void startTaskTracker() {
TaskTracker taskTracker = TaskTrackerBuilder.buildByProperties(quartzLTSConfig.getTaskTrackerProperties());
taskTracker.setWorkThreads(quartzJobContexts.size());
taskTracker.setJobRunnerClass(QuartzJobRunnerDispatcher.class);
final QuartzJobRunnerDispatcher jobRunnerDispatcher = new QuartzJobRunnerDispatcher(quartzJobContexts);
taskTracker.setRunnerFactory(new RunnerFactory() {
@Override
public JobRunner newRunner() {
return jobRunnerDispatcher;
}
});
taskTracker.start();
}
private JobClient startJobClient() {
JobClientProperties jobClientProperties = quartzLTSConfig.getJobClientProperties();
jobClientProperties.setUseRetryClient(false);
JobClient jobClient = JobClientBuilder.buildByProperties(jobClientProperties);
jobClient.start();
return jobClient;
}
private void submitJobs(JobClient jobClient) {
List jobs = new ArrayList(quartzJobContexts.size());
for (QuartzJobContext quartzJobContext : quartzJobContexts) {
if (QuartzJobType.CRON == quartzJobContext.getType()) {
jobs.add(buildCronJob(quartzJobContext));
} else if (QuartzJobType.SIMPLE_REPEAT == quartzJobContext.getType()) {
jobs.add(buildSimpleJob(quartzJobContext));
}
}
LOGGER.info("=============LTS=========== Submit start");
submitJobs0(jobClient, jobs);
LOGGER.info("=============LTS=========== Submit end");
}
private Job buildCronJob(QuartzJobContext quartzJobContext) {
CronTriggerImpl cronTrigger = (CronTriggerImpl) quartzJobContext.getTrigger();
String cronExpression = cronTrigger.getCronExpression();
String description = cronTrigger.getDescription();
int priority = cronTrigger.getPriority();
String name = quartzJobContext.getName();
Job job = new Job();
job.setTaskId(name);
job.setPriority(priority);
job.setCronExpression(cronExpression);
job.setSubmitNodeGroup(quartzLTSConfig.getJobClientProperties().getNodeGroup());
job.setTaskTrackerNodeGroup(quartzLTSConfig.getTaskTrackerProperties().getNodeGroup());
job.setParam("description", description);
setJobProp(job);
return job;
}
private Job buildSimpleJob(QuartzJobContext quartzJobContext) {
SimpleTriggerImpl simpleTrigger = (SimpleTriggerImpl) quartzJobContext.getTrigger();
String description = simpleTrigger.getDescription();
int priority = simpleTrigger.getPriority();
String name = quartzJobContext.getName();
int repeatCount = simpleTrigger.getRepeatCount();
long repeatInterval = simpleTrigger.getRepeatInterval();
Job job = new Job();
job.setTaskId(name);
job.setTriggerDate(simpleTrigger.getNextFireTime());
job.setRepeatCount(repeatCount);
if (repeatCount != 0) {
job.setRepeatInterval(repeatInterval);
}
job.setPriority(priority);
job.setSubmitNodeGroup(quartzLTSConfig.getJobClientProperties().getNodeGroup());
job.setTaskTrackerNodeGroup(quartzLTSConfig.getTaskTrackerProperties().getNodeGroup());
job.setParam("description", description);
setJobProp(job);
return job;
}
private void setJobProp(Job job) {
QuartzLTSConfig.JobProperties jobProperties = quartzLTSConfig.getJobProperties();
if (jobProperties == null) {
return;
}
if (jobProperties.getMaxRetryTimes() != null) {
job.setMaxRetryTimes(jobProperties.getMaxRetryTimes());
}
if (jobProperties.getNeedFeedback() != null) {
job.setNeedFeedback(jobProperties.getNeedFeedback());
}
if (jobProperties.getRelyOnPrevCycle() != null) {
job.setRelyOnPrevCycle(jobProperties.getRelyOnPrevCycle());
}
if (jobProperties.getReplaceOnExist() != null) {
job.setReplaceOnExist(jobProperties.getReplaceOnExist());
}
}
private void submitJobs0(JobClient jobClient, List jobs) {
List failedJobs = null;
try {
Response response = jobClient.submitJob(jobs);
if (!response.isSuccess()) {
LOGGER.warn("Submit Quartz Jobs to LTS failed: {}", JSON.toJSONString(response));
failedJobs = response.getFailedJobs();
}
} catch (Throwable e) {
LOGGER.warn("Submit Quartz Jobs to LTS error", e);
failedJobs = jobs;
}
if (CollectionUtils.isNotEmpty(failedJobs)) {
// 没提交成功要重试 3S 之后重试
LOGGER.info("=============LTS=========== Sleep 3 Seconds and retry");
QuietUtils.sleep(3000);
submitJobs0(jobClient, failedJobs);
return;
}
// 如果成功了, 关闭jobClient
jobClient.stop();
}
}