springboot2.0+Elastic Job动态job配置实现微服务调用

springboot2.0+Elastic Job实现微服务调用

本猿第一次写博客,写的不好勿喷

一、前提

本文只介绍如何把elastic-job和springcloud微服务集成,不对其他知识做介绍,需先掌握以下知识
1.会使用springboot
2.会使用springcloud FeignClient微服务
3.需自行搭建eureka server和config server
4.会使用zookeeper
5.会使用反射相关知识
6.了解当当定时任务:http://elasticjob.io/index_zh.html
二、定时任务集成

项目整体结构
springboot-elasticjob是定时任务
servicedemo是定时任务调用的服务(一个简单的服务这里不做过多介绍)
springboot2.0+Elastic Job动态job配置实现微服务调用_第1张图片
springboot2.0+Elastic Job动态job配置实现微服务调用_第2张图片
springboot-elasticjob
pom文件如下:


<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>

	<groupId>cn.schedulergroupId>
	<artifactId>springboot-elasticjobartifactId>
	<version>1.0.0-SNAPSHOTversion>
	<packaging>jarpackaging>

	<name>springboot-elasticjobname>
	<description>scheduler project for Spring Bootdescription>
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.0.3.RELEASEversion>
		<relativePath /> 
	parent>

	<properties>
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
		<spring-cloud.version>Finchley.RELEASEspring-cloud.version>
		<java.version>1.8java.version>
		<elastic-job.version>2.1.5elastic-job.version>
		<commons-lang3.version>3.4commons-lang3.version>
		<curator.version>2.10.0curator.version>
		<druid.spring.boot.version>1.1.9druid.spring.boot.version>
		<druid.version>1.1.9druid.version>
	properties>

	<dependencies>
		<dependency>
			<groupId>cn.demogroupId>
			<artifactId>apiartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-actuatorartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-configartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-openfeignartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logbackgroupId>
					<artifactId>logback-coreartifactId>
				exclusion>
				<exclusion>
					<groupId>org.apache.logging.log4jgroupId>
					<artifactId>log4j-apiartifactId>
				exclusion>
				<exclusion>
					<groupId>org.apache.logging.log4jgroupId>
					<artifactId>log4j-to-slf4jartifactId>
				exclusion>
				<exclusion>
					<groupId>ch.qos.logbackgroupId>
					<artifactId>logback-classicartifactId>
				exclusion>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-loggingartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-jdbcartifactId>
			<exclusions>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
			exclusions>
		dependency>

		<dependency>
			<groupId>mysqlgroupId>
			<artifactId>mysql-connector-javaartifactId>
			<scope>runtimescope>
		dependency>
		<dependency>
			<groupId>com.alibabagroupId>
			<artifactId>druid-spring-boot-starterartifactId>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
			<exclusions>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-configuration-processorartifactId>
			<optional>trueoptional>
		dependency>

		<dependency>
			<groupId>org.apache.curatorgroupId>
			<artifactId>curator-frameworkartifactId>
		dependency>
		<dependency>
			<groupId>org.apache.curatorgroupId>
			<artifactId>curator-clientartifactId>
			<exclusions>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>org.apache.zookeepergroupId>
			<artifactId>zookeeperartifactId>
			<exclusions>
				<exclusion>
					<groupId>log4jgroupId>
					<artifactId>log4jartifactId>
				exclusion>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-log4j12artifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<groupId>org.apache.curatorgroupId>
			<artifactId>curator-recipesartifactId>
		dependency>
		<dependency>
			<artifactId>elastic-job-common-coreartifactId>
			<groupId>com.dangdanggroupId>
			<exclusions>
				<exclusion>
					<groupId>org.slf4jgroupId>
					<artifactId>slf4j-apiartifactId>
				exclusion>
			exclusions>
		dependency>
		<dependency>
			<artifactId>elastic-job-lite-coreartifactId>
			<groupId>com.dangdanggroupId>
		dependency>
		<dependency>
			<artifactId>elastic-job-lite-springartifactId>
			<groupId>com.dangdanggroupId>
		dependency>
		<dependency>
			<groupId>org.apache.commonsgroupId>
			<artifactId>commons-lang3artifactId>
		dependency>
	dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
			<dependency>
				<groupId>org.apache.curatorgroupId>
				<artifactId>curator-recipesartifactId>
				<version>${curator.version}version>
			dependency>
			<dependency>
				<groupId>org.apache.curatorgroupId>
				<artifactId>curator-frameworkartifactId>
				<version>${curator.version}version>
			dependency>
			<dependency>
				<groupId>org.apache.curatorgroupId>
				<artifactId>curator-clientartifactId>
				<version>${curator.version}version>
			dependency>
			<dependency>
				<groupId>org.apache.zookeepergroupId>
				<artifactId>zookeeperartifactId>
				<version>3.4.6version>
			dependency>
			<dependency>
				<artifactId>elastic-job-common-coreartifactId>
				<groupId>com.dangdanggroupId>
				<version>${elastic-job.version}version>
			dependency>
			<dependency>
				<artifactId>elastic-job-lite-coreartifactId>
				<groupId>com.dangdanggroupId>
				<version>${elastic-job.version}version>
			dependency>
			<dependency>
				<artifactId>elastic-job-lite-springartifactId>
				<groupId>com.dangdanggroupId>
				<version>${elastic-job.version}version>
			dependency>
			<dependency>
				<groupId>com.alibabagroupId>
				<artifactId>druid-spring-boot-starterartifactId>
				<version>${druid.spring.boot.version}version>
			dependency>
			<dependency>
				<groupId>cn.demogroupId>
				<artifactId>apiartifactId>
				<version>1.0.0-SNAPSHOTversion>
			dependency>
		dependencies>
	dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
			plugin>
		plugins>
	build>
	<distributionManagement>
		<repository>
			<id>nexus.kelaile-releaseid>
			<url>http://127.0.0.1:8081/nexus/content/repositories/releases/url>
		repository>
		<snapshotRepository>
			<id>nexus.kelaile-snapshotid>
			<url>http://127.0.0.1:8081/nexus/content/repositories/snapshots/url>
		snapshotRepository>
	distributionManagement>


	<repositories>
		<repository>
			<id>nexus.kelaile-releaseid>
			<url>http://127.0.0.1:8081/nexus/content/groups/public/url>
			<releases>
				<enabled>trueenabled>
			releases>
			<snapshots>
				<enabled>trueenabled>
				<updatePolicy>alwaysupdatePolicy>
			snapshots>
		repository>
	repositories>
project>

配置信息:

server:
  port: 8080
spring:
  profiles:
    active: dev
  application:
    name: springboot-elasticjob
##配置中心    
  cloud: 
    config:
      username: username
      password: password 
      profile: ${spring.profiles.active}  
      discovery: 
        service-id: config-server
        enabled: true
##数据源        
  datasource: 
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/elastic_job?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
    username: root
    password: 123456
    druid:
      initial-size: 3
      max-active: 10
      min-idle: 5
      max-wait: 600000
      validation-query: SELECT 1
      test-on-borrow: true
      test-on-return: false
      test-while-idle: true
      time-between-eviction-runs-millis: 600000
      min-evictable-idle-time-millis: 600000
      filters: stat,wall        
       
info: 
  app_name: ${spring.application.name}
##注册中心
eureka: 
  client: 
    service-url: 
      defaultZone: http://username:password@127.0.0.1:9011/eureka/      
##zookeeper配置      
demo:
  elasticjob: 
    zk-config: 
      serverLists: localhost:2181
      namespace: elastic-job-lite-demo
      baseSleepTimeMilliseconds: 1000
      maxSleepTimeMilliseconds: 3000
      maxRetries: 4
      digest: 'password'
#DEMO-PROVIDER.ribbon.listOfServers: localhost:8088
#ribbon.eureka.enabled: false

首先看config包下的配置
JobEventConfig为JobEventRdbConfiguration配置数据源:

/*
 * Copyright 1999-2015 dangdang.com.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *

*/
package cn.demo.scheduler.config; import com.dangdang.ddframe.job.event.JobEventConfiguration; import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; import javax.sql.DataSource; /** * 为job配置数据源 * * @author xing * */ @Configuration public class JobEventConfig { @Resource private DataSource dataSource; @Bean public JobEventConfiguration jobEventConfiguration() { return new JobEventRdbConfiguration(dataSource); } }

RegistryCenterConfig配置zookeeper注册信息:

/*
 * Copyright 1999-2015 dangdang.com.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *

*/
package cn.demo.scheduler.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration; import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter; @Configuration @ConfigurationProperties(prefix = "demo.elasticjob.zk-config") public class RegistryCenterConfig { /** * 连接Zookeeper服务器的列表. 包括IP地址和端口号. 多个地址用逗号分隔. 如: host1:2181,host2:2181 */ private String serverLists; /** * 命名空间. */ private String namespace; /** * 等待重试的间隔时间的初始值. 单位毫秒. */ private int baseSleepTimeMilliseconds; /** * 等待重试的间隔时间的最大值. 单位毫秒. */ private int maxSleepTimeMilliseconds; /** * 最大重试次数. */ private int maxRetries; /** * 登录权限 */ private String digest; @Bean(initMethod = "init") public ZookeeperRegistryCenter zookeeperRegistryCenter() { ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration(serverLists, namespace); zookeeperConfiguration.setMaxRetries(maxRetries); zookeeperConfiguration.setBaseSleepTimeMilliseconds(baseSleepTimeMilliseconds); zookeeperConfiguration.setMaxSleepTimeMilliseconds(maxSleepTimeMilliseconds); zookeeperConfiguration.setDigest(digest); return new ZookeeperRegistryCenter(zookeeperConfiguration); } public String getServerLists() { return serverLists; } public void setServerLists(String serverLists) { this.serverLists = serverLists; } public String getNamespace() { return namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } public int getBaseSleepTimeMilliseconds() { return baseSleepTimeMilliseconds; } public void setBaseSleepTimeMilliseconds(int baseSleepTimeMilliseconds) { this.baseSleepTimeMilliseconds = baseSleepTimeMilliseconds; } public int getMaxSleepTimeMilliseconds() { return maxSleepTimeMilliseconds; } public void setMaxSleepTimeMilliseconds(int maxSleepTimeMilliseconds) { this.maxSleepTimeMilliseconds = maxSleepTimeMilliseconds; } public int getMaxRetries() { return maxRetries; } public void setMaxRetries(int maxRetries) { this.maxRetries = maxRetries; } public String getDigest() { return digest; } public void setDigest(String digest) { this.digest = digest; } }

接下来是每个定时任务的配置,这里我是把所有的配置放在了数据库表结构如下:
elastic_job_config任务配置表,elastic_job_config_log每次修改时进行备份

CREATE TABLE `elastic_job_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_name` varchar(255) NOT NULL COMMENT '作业名称',
  `cron` varchar(50) NOT NULL COMMENT 'cron表达式,用于控制作业触发时间',
  `sharding_total_count` int(3) NOT NULL COMMENT '作业分片总数',
  `sharding_item_parameters` varchar(255) DEFAULT NULL COMMENT '分片序列,列号从0开始,不可大于或等于作业分片总数.如:0=a,1=b,2=c',
  `job_parameter` varchar(255) DEFAULT NULL COMMENT '作业自定义参数',
  `failover` enum('false','true') DEFAULT 'true' COMMENT '是否开启任务执行失效转移',
  `misfire` enum('false','true') DEFAULT 'true' COMMENT '是否开启错过任务重新执行',
  `description` varchar(255) DEFAULT NULL COMMENT '作业描述信息',
  `job_class` varchar(255) NOT NULL COMMENT '作业实现类',
  `streaming_process` enum('false','true') DEFAULT 'true' COMMENT '是否流式处理数据(只有Dataflow类型支持)',
  `job_config` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `jobName` (`job_name`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

INSERT INTO `elastic_job_config` (
	`id`,
	`job_name`,
	`cron`,
	`sharding_total_count`,
	`sharding_item_parameters`,
	`job_parameter`,
	`failover`,
	`misfire`,
	`description`,
	`job_class`,
	`streaming_process`,
	`job_config`
)
VALUES
	(
		'1',
		'DemoSimpleJob',
		'1 1 1 * * ?',
		'1',
		'',
		'',
		'true',
		'true',
		'测试定时任务',
		'cn.demo.scheduler.task.DemoSimpleJob',
		'true',
		''
	);

CREATE TABLE `elastic_job_config_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_name` varchar(255) NOT NULL COMMENT '作业名称',
  `cron` varchar(50) NOT NULL COMMENT 'cron表达式,用于控制作业触发时间',
  `sharding_total_count` int(3) NOT NULL COMMENT '作业分片总数',
  `sharding_item_parameters` varchar(255) DEFAULT NULL COMMENT '分片序列,列号从0开始,不可大于或等于作业分片总数.如:0=a,1=b,2=c',
  `job_parameter` varchar(255) DEFAULT NULL COMMENT '作业自定义参数',
  `failover` enum('false','true') DEFAULT 'true' COMMENT '是否开启任务执行失效转移',
  `misfire` enum('false','true') DEFAULT 'true' COMMENT '是否开启错过任务重新执行',
  `description` varchar(255) DEFAULT NULL COMMENT '作业描述信息',
  `job_class` varchar(255) NOT NULL COMMENT '作业实现类',
  `streaming_process` enum('false','true') DEFAULT 'true' COMMENT '是否流式处理数据(只有Dataflow类型支持)',
  `job_config` text,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;


任务加载流程:在项目启动时读取数据库配置进行配置,当然也可以做成在页面上添加配置时同时向zookeeper中注册任务信息。
因为数据库里配置的是定时任务的全类名,这里通过反射进行实例化,无法使用spring的依赖注入对定时任务类中的属性进行初始化,所以我是用反射对有@Resource和@Autowired的属性赋值。
由于业务需求,我们需要添加一个额外的参数,数据库列名“job_config”,这个完全可以不要。

package cn.demo.scheduler.runner;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import com.dangdang.ddframe.job.api.ElasticJob;
import com.dangdang.ddframe.job.api.dataflow.DataflowJob;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
import com.dangdang.ddframe.job.config.dataflow.DataflowJobConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;

import cn.demo.scheduler.dao.ElasticJobConfigDao;
import cn.demo.scheduler.entity.ElasticJobConfigBean;
import cn.demo.scheduler.util.BeanTools;

/**
 * 定时任务配置
 * 
 * @author xing
 *
 */
@Component
public class ElasticJobRunner implements CommandLineRunner {

	private Logger log = LoggerFactory.getLogger(ElasticJobRunner.class);

	private static final Map<String, String> JOB_CONFIG_MAP = new HashMap<>();

	@Resource
	private ZookeeperRegistryCenter zookeeperRegistryCenter;

	@Resource
	private JobEventConfiguration jobEventConfiguration;

	@Resource
	private ElasticJobConfigDao elasticJobConfigDao;

	/**
	 * 根据jobName获取配置
	 * 
	 * @param jobName
	 * @return
	 */
	public static String getJobConfig(String jobName) {
		return JOB_CONFIG_MAP.get(jobName);
	}

	/**
	 * 更改jobConfig
	 * 
	 * @param jobName
	 * @param jobConfig
	 */
	public static void setJobConfig(String jobName, String jobConfig) {
		JOB_CONFIG_MAP.put(jobName, jobConfig);
	}

	/**
	 * 注入任务
	 * 
	 * @param elasticJobConfigBean
	 */
	@SuppressWarnings("unchecked")
	private void registryJob(ElasticJobConfigBean elasticJobConfigBean) {
		try {
			Class<? extends ElasticJob> jobClass = (Class<? extends ElasticJob>) Class
					.forName(elasticJobConfigBean.getJobClass());
			ElasticJob elasticJob = getInstance(jobClass);
			SpringJobScheduler jobScheduler = jobScheduler(elasticJob, jobClass, elasticJobConfigBean);
			jobScheduler.init();
			log.info("初始化定时任务 {} ", elasticJobConfigBean.toString());
		} catch (Exception e) {
			log.error("注册Job出错:{} ", elasticJobConfigBean.toString(), e);
		}

	}

	/**
	 * 通过反射对有@Resource和@Autowired的属性赋值
	 * 
	 * @param jobClass
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	private ElasticJob getInstance(Class<? extends ElasticJob> jobClass)
			throws InstantiationException, IllegalAccessException {
		Field[] declaredFields = jobClass.getDeclaredFields();
		ElasticJob newInstance = jobClass.newInstance();
		for (Field field : declaredFields) {
			Annotation[] annotations = field.getAnnotations();
			if (annotations == null || annotations.length == 0) {
				continue;
			}
			boolean flag = false;
			for (Annotation annotation : annotations) {
				Class<? extends Annotation> annotationType = annotation.annotationType();
				if (annotationType.equals(Resource.class) || annotationType.equals(Autowired.class)) {
					flag = true;
					break;
				}
			}
			if (flag) {
				field.setAccessible(true);
				field.set(newInstance, BeanTools.getBean(field.getType()));
			}
		}
		return newInstance;
	}

	/**
	 * 注册SpringJobScheduler
	 * 
	 * @param elasticJob
	 * @param jobClass
	 * @param elasticJobConfigBean
	 * @return
	 */
	private SpringJobScheduler jobScheduler(ElasticJob elasticJob, Class<? extends ElasticJob> jobClass,
			ElasticJobConfigBean elasticJobConfigBean) {
		LiteJobConfiguration build = LiteJobConfiguration.newBuilder(jobConfiguration(elasticJob, elasticJobConfigBean))
				.overwrite(true).build();
		SpringJobScheduler springJobScheduler = new SpringJobScheduler(elasticJob, zookeeperRegistryCenter, build,
				jobEventConfiguration);
		return springJobScheduler;
	}

	/**
	 * job配置
	 * 
	 * @param elasticJob
	 * @param elasticJobConfigBean
	 * @return
	 */
	private JobTypeConfiguration jobConfiguration(final ElasticJob elasticJob,
			ElasticJobConfigBean elasticJobConfigBean) {
		JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
				.newBuilder(elasticJobConfigBean.getJobName(), elasticJobConfigBean.getCron(),
						elasticJobConfigBean.getShardingTotalCount())
				.shardingItemParameters(elasticJobConfigBean.getShardingItemParameters())
				.misfire(Boolean.valueOf(elasticJobConfigBean.getMisfire()))
				.description(elasticJobConfigBean.getDescription())
				.failover(Boolean.valueOf(elasticJobConfigBean.getFailover()))
				.jobParameter(elasticJobConfigBean.getJobParameter())
				.build();
		if (elasticJob instanceof SimpleJob) {
			return new SimpleJobConfiguration(jobCoreConfiguration, elasticJob.getClass().getCanonicalName());
		}
		if (elasticJob instanceof DataflowJob) {
			return new DataflowJobConfiguration(jobCoreConfiguration, elasticJob.getClass().getCanonicalName(),
					Boolean.valueOf(elasticJobConfigBean.getStreamingProcess()));
		}
		throw new RuntimeException("未知类型定时任务:" + elasticJob.getClass().getName());
	}

	@Override
	public void run(String... args) throws Exception {
		List<ElasticJobConfigBean> elasticJobConfigList = elasticJobConfigDao.getElasticJobConfigList();
		if (elasticJobConfigList == null || elasticJobConfigList.size() == 0) {
			return;
		}
		elasticJobConfigList.forEach(elasticJobConfig -> {
			registryJob(elasticJobConfig);
			JOB_CONFIG_MAP.put(elasticJobConfig.getJobName(), elasticJobConfig.getJobConfig());
		});
	}
}


启动类上要注意扫描FeignClient

package cn.demo.scheduler;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringCloudApplication
@ComponentScan(value = { "cn.demo.scheduler"})
@EnableFeignClients(basePackages = { "cn.demo.api" })
public class ScheduleApplication {

	public static void main(String[] args) {
		SpringApplication.run(ScheduleApplication.class, args);
	}
}

定时任务类DemoSimpleJob:

package cn.demo.scheduler.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;

import cn.demo.api.TestBean;
import cn.demo.api.TestService;

public class DemoSimpleJob implements SimpleJob {

	private Logger log = LoggerFactory.getLogger(DemoSimpleJob.class);

	@Autowired
	private TestService testService;

	@Override
	public void execute(ShardingContext shardingContext) {
		String jobParameter = shardingContext.getJobParameter();
		log.info("test--------------------{}", jobParameter);
		TestBean testBean = new TestBean();
		testBean.setId("123");
		testBean.setName("Hello World!");
		TestBean test = testService.test(testBean);
		log.info(test.toString());
	}

}

然后做了一个简单的界面用来管理每个任务初始化配置
springboot2.0+Elastic Job动态job配置实现微服务调用_第3张图片

这里的controller、service、dao是定时任务配置的增删改查,不做过多介绍。
接下来就是去当当的开源定时任务管理上配置定时任务:
springboot2.0+Elastic Job动态job配置实现微服务调用_第4张图片

源码见:https://github.com/dcw2020520/springboot-elasticjob

你可能感兴趣的:(springboot)