1、介绍
我们可以先思考一下业务场景的解决方案:
- 某电商系统需要在每天上午 10点,下午3点,晚上8点发放一批优惠券。
- 某银行系统需要在信用卡到期还款日的前三天进行短信提醒。
- 某财务系统需要在每天凌晨 0:10结算前一天的财务数据,统计汇总。
- 12306 会根据车次的不同,设置某几个时间点进行分批放票。
- 某网站为了实现天气实时展示,每隔 10分钟就去天气服务器获取最新的实时天气信息。
Elastic-job:当当网借鉴TBSchedule并基于quartz二次开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,具有任务高可用以及分片功能。
cron表达式
cron表达式是一个字符串, 用来设置定时规则, 由七部分组成, 每部分中间用空格隔开, 每部分的含义如下表所示:
2、基本使用
1. 版本要求
- JDK 要求1.7及以上版本
- Maven 要求3.0.4及以上版本
- zookeeper 要求采用3.4.6及以上版本
2. Zookeeper安装&运行
- Zookeeper类似于Eureka,用来进行微服务注册和管理
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>2.1.5</version>
</dependency>
server.port=${PORT:57081}
spring.application.name = elastic-job-springboot
logging.level.root = info
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mp?serverTimezone=GMT%2B8&useSSL=false
spring.datasource.username=root
spring.datasource.password=mysql
# 设置Mapper接口所对应的XML文件位置
mybatis-plus.mapper-locations = classpath*:dao/*.xml
# 设置别名包扫描路径
mybatis-plus.type-aliases-package = com.spring.elastic.pojo
# zookeeper服务地址
zookeeper.connString = localhost:2181
# 名称空间
myjob.namespace = elastic-job-example
# 分片总数
myjob.count = 3
# cron表达式(定时策略)
myjob.cron = 0/10 * * * * ?
//SELECT * FROM tb_user WHERE MOD(id,分片数) = 分片值
@Select("SELECT * FROM tb_user WHERE MOD(id,#{shardingTotalCount}) = #{shardingItem}")
//job配置类
@Configuration
public class JobConfig {
@Autowired
MyJob myJob;
@Autowired
ZookeeperRegistryCenter registryCenter;
@Value("${myjob.count}")
private int shardingCount;
@Value("${myjob.cron}")
private String cron;
/**
* 配置任务详细信息
* @param jobClass 任务执行类
* @param cron 执行策略
* @param shardingTotalCount 分片数量
* @return
*/
private LiteJobConfiguration createJobConfiguration(final Class<? extends SimpleJob> jobClass,
final String cron,
final int shardingTotalCount){
//创建JobCoreConfigurationBuilder
JobCoreConfiguration.Builder JobCoreConfigurationBuilder =
JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount);
JobCoreConfiguration jobCoreConfiguration =
JobCoreConfigurationBuilder.build();
//创建SimpleJobConfiguration
SimpleJobConfiguration simpleJobConfiguration =
new SimpleJobConfiguration(jobCoreConfiguration, jobClass.getCanonicalName());
//创建LiteJobConfiguration
LiteJobConfiguration liteJobConfiguration =
LiteJobConfiguration.newBuilder(simpleJobConfiguration)
.jobShardingStrategyClass("com.dangdang.ddframe.job.lite.api.strategy.impl.AverageAllocationJobShardingStrategy")
.overwrite(true)
.build();
return liteJobConfiguration;
}
@Bean(initMethod = "init")
public SpringJobScheduler initSimpleElasticJob() {
//创建SpringJobScheduler
SpringJobScheduler springJobScheduler = new SpringJobScheduler(myJob, registryCenter,
createJobConfiguration(myJob.getClass(), cron,shardingCount));
return springJobScheduler;
}
}
@Configuration
public class ZkConfig {
//zookeeper服务地址
@Value("${zookeeper.connString}")
private String ZOOKEEPER_CONNECTION_STRING ;
//定时任务命名空间
@Value("${myjob.namespace}")
private String JOB_NAMESPACE;
//zk的配置及创建注册中心
@Bean(initMethod = "init")
public ZookeeperRegistryCenter setUpRegistryCenter(){
//zk的配置
ZookeeperConfiguration configuration = new
ZookeeperConfiguration(ZOOKEEPER_CONNECTION_STRING,JOB_NAMESPACE);
//创建注册中心
ZookeeperRegistryCenter zookeeperRegistryCenter = new ZookeeperRegistryCenter(configuration);
return zookeeperRegistryCenter;
}
}
/*
*数据查询任务
*/
@Component
public class MyJob implements SimpleJob {
@Autowired
private UserMapper userMapper;
@Override
public void execute(ShardingContext shardingContext) {
int count = shardingContext.getShardingTotalCount();
int item = shardingContext.getShardingItem();
List<User> userList = userMapper.queryById(count, item);
for (User user : userList) {
System.out.println("作业分片:"+item+"---->"+user);
}
}
}