在之前的springboot整合elastic-job篇中,我们了解到,elastic-job是一个不错的任务调度框架,本篇将进一步说明,如何使用elastic-job实现常用的动态任务的执行场景
zookeeper安装与启动(本地可以使用windows版,比较快捷)
1、添加基础pom依赖
org.springframework.boot
spring-boot-starter-parent
2.2.1.RELEASE
3.3.0
3.3.0
2.9.2
1.9.6
io.springfox
springfox-swagger2
${swagger.version}
io.springfox
springfox-swagger-ui
${swagger.version}
com.github.xiaoymin
swagger-bootstrap-ui
${swagger-bootstrap-ui.version}
com.dangdang
elastic-job-lite-core
2.1.5
com.dangdang
elastic-job-lite-spring
2.1.5
org.springframework.boot
spring-boot-starter-web
2.2.1.RELEASE
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
8.0.11
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus-boot-starter.version}
com.baomidou
mybatis-plus-generator
${mybatis-plus-generator.version}
org.projectlombok
lombok
1.18.0
2、配置文件配置zk信息
elastic-job的任务调度,在运行的时候依赖zk,因此需要根据自身情况配置zk,可以理解为任务需要结合zk的节点进行使用,如果不需要数据库连接可以忽略
server.port=8081
# zookeeper集群
elaticjob.zookeeper.server-lists=127.0.0.1:2181
elaticjob.zookeeper.namespace=updatetask
#动态配置
zkserver= 127.0.0.1:2181
zknamespace=zknamespce
#动态配置2
elasticjob.serverlists=127.0.0.1:2181
elasticjob.namespace=boot-job
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://IP:3306/dbname?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
mybatis-plus.global-config.db-column-underline=true
mybatis-plus.global-config.db-config.id-type=uuid
mybatis-plus.global-config.db-config.field-strategy=not_null
mybatis-plus.global-config.refresh=true
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3、配置ElasticJob相关
包括zk注册中心,elastic-job监听器等
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
public class ElasticJobConfig {
@Value("${elasticjob.serverlists}")
private String serverLists;
@Value("${elasticjob.namespace}")
private String namespace;
@Bean
public ZookeeperConfiguration zConfig(){
return new ZookeeperConfiguration(serverLists, namespace);
}
@Bean(initMethod = "init")
public ZookeeperRegistryCenter registryCenter(ZookeeperConfiguration config){
return new ZookeeperRegistryCenter(config);
}
@Bean
public ElasticJobListener elasticJobListener(){
return new ElasticJobListener(1000L, 10000L);
}
}
4、动态任务处理配置类
主要包括动态任务的增删改
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.internal.schedule.JobRegistry;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class ElasticJobHandler {
@Resource
private ZookeeperRegistryCenter registryCenter;
@Resource
private ElasticJobListener elasticJobListener;
private static LiteJobConfiguration.Builder simpleJobConfigBuilder(String jobName,
Class extends SimpleJob> jobClass,
int shardTotalCount,
String cron,
String id) {
return LiteJobConfiguration.newBuilder(new SimpleJobConfiguration(
JobCoreConfiguration.newBuilder(jobName,cron,shardTotalCount).jobParameter(id).build(),jobClass.getCanonicalName()
));
}
/**
* 添加定时任务
*/
public void addJob(String jobName, SimpleJob jobInstance, String cron, Integer shardTotalCount, String id) {
LiteJobConfiguration jobConfig = simpleJobConfigBuilder(jobName, jobInstance.getClass(), shardTotalCount, cron, id)
.overwrite(true).build();
new SpringJobScheduler(jobInstance,registryCenter,jobConfig,elasticJobListener).init();
}
/**
* 修改定时任务
* @param jobName
* @param cron
*/
public void updateJob(String jobName, String cron) {
JobRegistry.getInstance().getJobScheduleController(jobName).rescheduleJob(cron);
}
/**
* 移除定时任务
* @param jobName
*/
public void removeJob(String jobName){
JobRegistry.getInstance().getJobScheduleController(jobName).shutdown();
}
}
5、接口实现任务的增删改
import com.congge.task.config.ElasticJobHandler;
import com.congge.task.config.MyElasticJob;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/task")
public class ElasticController {
@Autowired
private ElasticJobHandler jobHandler;
@GetMapping("/add")
public Object addJob(String jobName,String cronExpress){
if(StringUtils.isEmpty(jobName)){
jobName = "test-job";
}
if(StringUtils.isEmpty(cronExpress)){
cronExpress = "1/5 * * * * ?";
}
jobHandler.addJob(jobName, new MyElasticJob(), cronExpress, 1, "1");
return "add success";
}
@GetMapping("/update")
public Object updateJob(String jobName,String cronExpress){
if(StringUtils.isEmpty(jobName)){
jobName = "test-job";
}
if(StringUtils.isEmpty(cronExpress)){
cronExpress = "1/5 * * * * ?";
}
jobHandler.updateJob(jobName,cronExpress);
return "update success";
}
@GetMapping("/remove")
public Object removeJob(String jobName){
jobHandler.removeJob(jobName);
return "remove success";
}
}
下面来测试一下接口是否好用,我们先来添加一个任务
可以看到,后台已经开始执行任务,由于我们没有给执行cron,默认值每隔5秒执行一次
当然,我们也可以连接elastic-job的控制台,看到我们后台正在运行的job,可以通过管控台对job进行处理,比如我们停止这个job
当点击关闭之后,任务将不再执行
经常有这样的场景,我们需要对数据库的某个表的数据进行状态值修改,或者定时备份某个表的数据,或者执行一些特殊任务等,都可以使用elastic-job来完成
具体来说,只需要在实现了SimpleJob的类中的execute方法里面去做就可以了,例如有这样一个场景,每隔5秒需要对user表中状态为1的数据进行修改
那么就可以直接改造MyElasticJob这个类
public class MyElasticJob implements SimpleJob {
UserService userService = SpringContextUtil.getBean("userService");
@Override
public void execute(ShardingContext shardingContext) {
String jobName = shardingContext.getJobName();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
System.out.println("任务:" + jobName +",执行" + "时间:" + simpleDateFormat.format(new Date()));
//执行具体的任务
userService.changeStatus();
}
}
如果有更多的业务要处理,可以类似的操作,下面启动工程,添加一个任务来执行下,看看是否能打到预期的目的,
以上是本文的全部内容,实际应用中,还需要结合较多的因素进行改造,希望对您有帮助哦
有需要源码的同学可前往下载:https://download.csdn.net/download/zhangcongyi420/22501493