最近在做定时发送问题,如果不是两张表混合展示的话,一个发布时间即可搞定,但是由于是两张表混合展示的,所以一个发布时间并不能解决问题,因为lz认为自己的线程知识太烂,所以未敢涉足线程,就在定时任务方向寻找解决方法,以下是我使用的动态修改定时任务的方法,仅供参考,欢迎各位大佬批评指正。
因为要动态修改cron,所以不能采用xml配置
首先,书写配置类
dubbo.registry.address.task=ip:2181
task_namespace=service_task
/**
* 定时人配置
*
* @author johny
* @date 2019/6/4
*/
@Configuration
public class ElasticJobConfig {
//配置文件中的zookeeper的ip和端口
@Value(value = "${dubbo.registry.address.task}")
private String serverlists;
//指定一个命名空间
@Value("${task_namespace}")
private String namespace;
@Bean
public ZookeeperConfiguration zkConfig() {
return new ZookeeperConfiguration(serverlists, namespace);
}
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter(ZookeeperConfiguration config) {
return new ZookeeperRegistryCenter(config);
}
@Bean
public ElasticJobListener elasticJobListener() {
//初始化要给定超时多少秒重连
return new ElasticJobListener(100, 100);
}
}
定时任务监听(只是为了可以动态执行下一条任务)
/**
* 定时任务监听
*
* @author johny
* @date 2019/6/4
*/
public class ElasticJobListener extends AbstractDistributeOnceElasticJobListener {
@Autowired
ElasticJobHandler elasticJobHandler;
public ElasticJobListener(long startedTimeoutMilliseconds, long completedTimeoutMilliseconds) {
super(startedTimeoutMilliseconds, completedTimeoutMilliseconds);
}
@Override
public void doBeforeJobExecutedAtLastStarted(ShardingContexts shardingContexts) {
System.out.println("========初始化任务前========");
System.out.println(shardingContexts.getJobParameter());
System.out.println(new Date());
}
@Override
public void doAfterJobExecutedAtLastCompleted(ShardingContexts shardingContexts) {
System.out.println("=======初始化任务后=============");
elasticJobHandler.addPublishJob();
}
}
这个handler 是重点,交给spring管理,其他地方直接调用此类即可
/**
* 定时任务添加
*
* @author johny
* @date 2019/6/4
*/
@Component
public class ElasticJobHandler {
public static final String CRON_DATE_FORMAT = "ss mm HH dd MM ? yyyy";
public static final String DATE_FORMAT = "ss mm HH dd MM ? yyyy";
@Resource
private ZookeeperRegistryCenter registryCenter;
@Resource
private ElasticJobListener elasticJobListener;
/**
*这个是任务持久层
*/
@Autowired
TaskService TaskService;
/**
* @param jobName
* @param jobClass
* @param shardingTotalCount
* @param cron
* @param id 数据ID
* @return
*/
private static LiteJobConfiguration.Builder simpleJobConfigBuilder(String jobName,
Class<? extends SimpleJob> jobClass,
int shardingTotalCount,
String cron,
String id) {
LiteJobConfiguration.Builder builder = LiteJobConfiguration.newBuilder(new SimpleJobConfiguration(
JobCoreConfiguration.newBuilder(jobName, cron, shardingTotalCount).jobParameter(id).build(), jobClass.getCanonicalName()));
builder.overwrite(true);
return builder;
}
/**
* 添加一个定时任务
*/
//此注解为开机自启
@PostConstruct
public void addPublishJob() {
Date date = null;
String id = "";
try {
JSONObject object = TaskService.qryTop();
if (object == null) {
return;
}
date = object.getDate("date");
id = object.getString("feedId");
} catch (Exception e) {
e.printStackTrace();
LogUtils.writeErrorLog(this.getClass().getName(), "查询定时任务异常", "qryTop", "", "", e.getMessage());
}
if (date == null) {
return;
}
//得到执行时间
String cron = getCron(date);
//shardingTotalCount分片数,多机时,分片为1,任务不会被重复执行
//overwrite为是否覆盖
int shardingTotalCount=1;
//"publishFeedTask"这是一个任务名称,相投的话overwrite(true)时会覆盖原有任务。
String jobName ="publishTask";
LiteJobConfiguration jobConfig = simpleJobConfigBuilder(jobName, PublishFeedTask.class, shardingTotalCount,
cron, id).overwrite(true).build();
System.out.println(cron + "======" + id);
//PublishTask为具体的任务执行逻辑类
new SpringJobScheduler(new PublishTask(TaskService), registryCenter, jobConfig, elasticJobListener).init();
}
/**
* 获得定时
*
* @param date
* @return
*/
public static String getCron(final Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(CRON_DATE_FORMAT);
String formatTimeStr = "";
if (date != null) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
}
任务具体逻辑类PublishTask.java
/**
* 发布feed
*
* @author johny
* @date 2019/6/4
*/
public class PublishTask implements SimpleJob {
TaskService taskService;
public PublishTask(TaskService taskService) {
this.taskService = taskService;
}
@Override
public void execute(ShardingContext shardingContext) {
String id = shardingContext.getJobParameter();
long feedId = Long.parseLong(id);
try {
//具体任务逻辑
} catch (Exception e) {
e.printStackTrace();
LogUtils.writeErrorLog(this.getClass().getName(), "定时发布", "PublishTask",
"system", e.getMessage());
}
}
}
其他地方直接引用即可
@Autowired
ElasticJobHandler elasticJobHandler;
elasticJobHandler.addPublishJob();