SpringBoot整合Elastic-Job分布式定时任务框架
package com.zcw.springbootelasticjob;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootElasticjobApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootElasticjobApplication.class, args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zcw</groupId>
<artifactId>springboot-elasticjob</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-elasticjob</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--elasic-job-->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>2.1.5</version>
</dependency>
<!--添加配置文件的注解类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server.port=8074
elasticjob.zookeeper.namespace=springboot-elasticjob
elasticjob.zookeeper.server-list=localhost:2181
package com.zcw.autoconfig;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName : ZookeeperAutoConfig
* @Description :自动配置类
* @Author : Zhaocunwei
* @Date: 2020-06-05 12:39
*/
@Configuration
@ConditionalOnProperty("elasticjob.zookeeper.server-list")
@EnableConfigurationProperties(ZookeeperProperties.class)
public class ZookeeperAutoConfig {
private final ZookeeperProperties zookeeperProperties;
public ZookeeperAutoConfig(ZookeeperProperties zookeeperProperties) {
this.zookeeperProperties = zookeeperProperties;
}
@Bean(initMethod = "init")
public CoordinatorRegistryCenter zkCenter(){
String serverList = zookeeperProperties.getServerlist();
String namespace = zookeeperProperties.getNamespace();
ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration(serverList, namespace);
ZookeeperRegistryCenter zookeeperRegistryCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
return zookeeperRegistryCenter;
}
}
package com.zcw.autoconfig;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @ClassName : ZookeeperProperties
* @Description : 属性配置类
* @Author : Zhaocunwei
* @Date: 2020-06-05 12:29
*/
@Getter@Setter
@ConfigurationProperties(prefix = "elasticjob.zookeeper")
public class ZookeeperProperties {
//zookeeper地址列表
private String serverlist;
//zookeeper命名空间
private String namespace;
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zcw.autoconfig.ZookeeperAutoConfig
server.port=8074
elasticjob.zookeeper.namespace=springboot-elasticjob
elasticjob.zookeeper.server-list=localhost:2181
package com.zcw.autoconfig;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//表示使用在哪:这里是类,
@Retention(RetentionPolicy.RUNTIME)//表示运行时进行启动
public @interface ElasticSimpleJob {
String jobName() default "";
String cron() default "";
int shardingTotalCount() default 1;
boolean overwrite() default false;
}
package com.zcw.springbootelasticjob.job;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.zcw.autoconfig.ElasticSimpleJob;
import lombok.extern.slf4j.Slf4j;
/**
* @ClassName : MySimpleJob
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-05 13:07
*/
@Slf4j
@ElasticSimpleJob(jobName = "mySimpleJob",
cron = "0/10 * * * * ?",
shardingTotalCount = 2,
overwrite = true)
@Component
public class MySimpleJob implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
log.info("我是分片项:"+shardingContext.getShardingItem()+",总分片数是:"+
shardingContext.getShardingTotalCount());
}
}
package com.zcw.autoconfig;
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.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.Map;
/**
* @ClassName : SimpleJobAutoConfig
* @Description : Simple类型对象,自动配置
* @Author : Zhaocunwei
* @Date: 2020-06-05 13:21
*/
@Configuration
@ConditionalOnBean(CoordinatorRegistryCenter.class)
@AutoConfigureAfter(ZookeeperAutoConfig.class)
public class SimpleJobAutoConfig {
@Autowired
private CoordinatorRegistryCenter coordinatorRegistryCenter;
@Autowired
private ApplicationContext applicationContext;
//自动注册
@PostConstruct
public void initSimpleJob(){
//获取spring的上下文
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(ElasticSimpleJob.class);
for(Map.Entry<String,Object> entry: beansWithAnnotation.entrySet()){
Object instance = entry.getValue();
Class<?>[] interfaces = instance.getClass().getInterfaces();
for (Class<?> superInterface : interfaces) {
if(superInterface == SimpleJob.class){
ElasticSimpleJob annotation = instance.getClass().getAnnotation(ElasticSimpleJob.class);
String jobName = annotation.jobName();
String cron = annotation.cron();
int shardingTotalCount = annotation.shardingTotalCount();
boolean overwrite =annotation.overwrite();
//注册定时任务
//job 核心配置
JobCoreConfiguration buildJcc = JobCoreConfiguration
.newBuilder(jobName, cron, shardingTotalCount)
.build();
//job类型配置
SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(
buildJcc, instance.getClass().getCanonicalName()
);
// job配置(LiteJobConfiguration)
LiteJobConfiguration buildLiteJobConfiguration = LiteJobConfiguration
.newBuilder(simpleJobConfiguration)
.overwrite(overwrite)
.build();
//启动
new JobScheduler(coordinatorRegistryCenter,buildLiteJobConfiguration).init();
}
}
}
}
}
package com.zcw.autoconfig;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ElasticDataflowJob {
String jobName() default "";
String cron() default "";
int shardingTotalCount() default 1;
boolean overwrite() default false;
boolean streamingProcess() default false;
}
package com.zcw.springbootelasticjob.job;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.zcw.autoconfig.ElasticDataflowJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @ClassName : MyDataflowJob
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-05 14:53
*/
@Slf4j
@Component
@ElasticDataflowJob(
jobName = "myDataflowJob",
cron = "0/10 * * * * ?",
shardingTotalCount = 2,
overwrite = true,
streamingProcess=true
)
public class MyDataflowJob implements DataflowJob<Integer> {
private List<Integer> list = new ArrayList<>();
{
list.add(0);
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);
list.add(8);
list.add(9);
}
@Override
public List<Integer> fetchData(ShardingContext shardingContext) {
List<Integer> rtnList = new ArrayList<>();
//数字%分片总数 ==当前分片项
for (Integer index:list){
if(index % shardingContext.getShardingTotalCount()==shardingContext.getShardingItem()){
rtnList.add(index);
break;
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("我是分片项:"+shardingContext.getShardingItem()+",我是抓取的数据是:"+rtnList);
return rtnList;
}
@Override
public void processData(ShardingContext shardingContext, List<Integer> data) {
list.removeAll(data);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("我是分片项:"+shardingContext.getShardingItem()+",我移除了数据:"+data);
}
}
package com.zcw.autoconfig;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter;
import com.zcw.springbootelasticjob.job.MyDataflowJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @ClassName : DataflowJobAutoConfig
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-06-05 15:32
*/
@Configuration
@ConditionalOnBean(CoordinatorRegistryCenter.class)
@AutoConfigureAfter(ZookeeperAutoConfig.class)
public class DataflowJobAutoConfig {
@Autowired
private CoordinatorRegistryCenter coordinatorRegistryCenter;
@Autowired
private ApplicationContext applicationContext;
public void initDataflowJob(){
Map<String, Object> beans = applicationContext
.getBeansWithAnnotation(ElasticDataflowJob.class);
for(Map.Entry<String,Object> entry:beans.entrySet()){
Object instance = entry.getValue();
Class<?>[] interfaces = instance.getClass().getInterfaces();
for(Class<?> superInterface:interfaces){
if(superInterface == DataflowJob.class){
ElasticDataflowJob annotation = instance.getClass().getAnnotation(ElasticDataflowJob.class);
String jobName = annotation.jobName();
String cron =annotation.cron();
int shardingTotalCount = annotation.shardingTotalCount();
boolean overwrite = annotation.overwrite();
boolean streamingProcess =annotation.streamingProcess();
//job核心配置
JobCoreConfiguration buildJobCoreConfiguration = JobCoreConfiguration
.newBuilder(jobName, cron, shardingTotalCount)
.build();
//job类型配置
DataflowJobConfiguration dataflowJobConfiguration = new DataflowJobConfiguration(
buildJobCoreConfiguration,
instance.getClass().getCanonicalName(),
streamingProcess);
//job根的配置(LiteJobConfiguration)
LiteJobConfiguration buildLiteJobConfiguration = LiteJobConfiguration
.newBuilder(dataflowJobConfiguration)
.overwrite(overwrite)
.build();
new JobScheduler(coordinatorRegistryCenter,buildLiteJobConfiguration)
.init();
}
}
}
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zcw.autoconfig.ZookeeperAutoConfig,\
com.zcw.autoconfig.DataflowJobAutoConfig