替换的原因:
我想用quartz实现定时任务集群的时候,遇到过很坑的问题就是所有做集群的机器都必须保证时间的一致性,要不然有很多机器的项目是起不来的;除此之外,使用quartz很容易造成数据库死锁的问题,虽然我已经降低了quartz的数据库事务级别,但还是有这种情况发生,所以用过一段时间之后,新的项目就用了elastic-job。
版本:
elastic-job有两个版本:一个是elastic-job-lite,一个是elastic-job-cloud;一般情况下elastic-job-lite就满足了,我在项目中用的也是这个,elastic-job-cloud是基于mesos的,虽然功能比lite多,但感觉lite就够用了,如果有对cloud感兴趣的同学可以取官网http://elasticjob.io/看下。
使用:
其实他的使用方法在官网都可以找得到,我的是基于springboot的:
1、在application-properties中配置注册中心和事件追踪数据源
#elastic-job集群支持 开始*************************************************
#zookpeer注册中心配置
regCenter.serverList=192.168.40.23:2181
regCenter.namespace=cron-provider
#elastic-job事件追踪数据库配置
jobEventConfig.url=jdbc:mysql://192.168.40.23:3306/youjia_cron?useUnicode=true&characterEncoding=UTF-8
jobEventConfig.driverClassName=com.mysql.jdbc.Driver
jobEventConfig.username=kudev_w
jobEventConfig.password=nBVHe1M/Q3TKmtLBPseVnVOeFO7jO1Ww
#elastic-job集群支持 结束*************************************************
2、配置注册中心
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 定时任务注册中心配置
*
* @author 高仕立
* @date 2017/12/18 16:54
*/
@Configuration
@ConditionalOnExpression("'${regCenter.serverList}'.length() > 0")
public class RegistryCenterConfig {
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter(@Value("${regCenter.serverList}") final String serverList, @Value("${regCenter.namespace}") final String namespace) {
return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
}
}
3、配置事件追踪数据源
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;
import com.youjia.cron.common.util.EncryptUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 定时器时事件数据源配置
*
* @author 高仕立
* @date 2017/12/18 16:36
*/
@Configuration
public class JobEventConfig {
@Bean
public JobEventConfiguration jobEventConfiguration(@Value("${jobEventConfig.url}") final String url, @Value("${jobEventConfig.driverClassName}") final String driverClassName,
@Value("${jobEventConfig.username}") final String username, @Value("${jobEventConfig.password}") final String password) {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(EncryptUtils.decrypt(password));
return new JobEventRdbConfiguration(dataSource);
}
}
4、配置定时任务常量,如果分片为1,部署多台服务的时候,自动切换为主从
package com.youjia.cron.config.elastic_job;
/**
* 定时任务常量相关配置类
*
* @author 高仕立
* @date 2017/12/19 10:10
*/
public class JobParamtersConfig {
/**
* 测试定时
*/
public static String test_cron = "0/1 * * * * ?";
/**
* 测试作业分片总数
*/
public static int test_total_count = 2;
/**
* 测试分片序列号和参数
*/
public static String test_shardingItemParameters = "0=A,1=B";
}
5、配置定时任务job
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.youjia.cron.common.constants.SmartLockConstant;
import com.youjia.cron.dao.lock.LodLockApplyMapper;
import com.youjia.cron.dao.lodjoinexamine.LodPreOnlineExample;
import com.youjia.cron.dao.lodjoinexamine.LodPreOnlineMapper;
import com.youjia.cron.model.lock.LodLockApply;
import com.youjia.cron.model.lock.LodLockApplyExample;
import com.youjia.cron.service.lock.third.huohe.HuoheTech;
import com.youjia.found.exception.YJException;
import com.youjia.lodge.model.LodPreOnline;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 测试定时模块
*
* @author 高仕立
* @date 2017/12/14 14:29
*/
@Component
public class TestJob implements SimpleJob {
private static final Logger logger = LoggerFactory.getLogger(TestJob.class);
@Override
public void execute(ShardingContext context) {
System.out.println("现在的日期是:" + new Date());
}
}
6、初始化定时任务:
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.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
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 com.youjia.cron.job.test.TestJob;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @author 高仕立
* @date 2017/12/18 16:55
*/
@Configuration
public class SimpleJobConfig {
@Resource
private ZookeeperRegistryCenter regCenter;
@Resource
private JobEventConfiguration jobEventConfiguration;
@Bean
public SimpleJob testJob(){
return new TestJob();
}
/**
* 初始化测试定时任务
*
* @return
*/
@Bean(initMethod = "init")
public JobScheduler simpleTestJobScheduler(final SimpleJob testJob) {
return new SpringJobScheduler(testJob, regCenter, getTestJobConfiguration(), jobEventConfiguration);
}
/**
* 配置测试定时任务
*
* @return
*/
private LiteJobConfiguration getTestJobConfiguration() {
return LiteJobConfiguration.newBuilder(
new SimpleJobConfiguration(
JobCoreConfiguration.newBuilder(TestJob.class.getCanonicalName(), test_cron, test_total_count)
.shardingItemParameters(test_shardingItemParameters).description
("测试定时任务").build(), TestJob.class.getCanonicalName())
).overwrite(true).monitorPort(9091).build();
}
}
监控:
从git上下载官方的源代码https://github.com/elasticjob/elastic-job-lite:
编译一下代码中的elastic-job下的console模块,会生成一个tar包,解压之后会生成bin目录,如果是windows平台的启动
start.bat,如果是linux,需要将start.sh的编码转换一下才可以运行;
效果图如下: