背景
因为有企业级批处理需求,具体到应用场景就是在三方支付系统中,日切后要进行清分结算的跑批处理。所以使用到成熟的spring batch,依托其强大且灵活的批量处理功能,再加上elastic任务调度整合来实现清分结算业务流程。本文章就是分别说明了elastic和spring-batch + mybatis的常规使用和两者的整合,仅供大家参考。。
项目整体结构
就先把elastic和spring-batch+mybatis整合的项目工程结构列出来,该工程实现包括:
- Elastic多种作业类型的开发和使用
- 通过Elastic调度spring-batch作业,将数据库中存储行业信息记录按照id的奇偶分别查询出来,写入两个不同的文件中。(也就是通过elastic的分片作业开发实现)
- Elastic-console管理控制台的界面手动触发操作
Elastic-Lite-Job
Elastic是一个分布式任务调度框架,可以利用zookeeper作为调度中心,通过管理控制台对任务进行手动关闭、触发、重启,并支持并行调度和任务分片,对spring支持也友好。具体参考官方文档。
- 整体架构图(图片来源官网)
- 配置依赖
不多说,直接参考官网依赖maven进行配置:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<latest.release.version>2.1.5</latest.release.version>
</properties>
<!-- 添加elastic-job -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>${latest.release.version}</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>${latest.release.version}</version>
</dependency>
<!-- end -->
在pom.xml配置即可。
- 作业开发
配置了elastic的两种作业类型:简单作业和流式处理作业。
SimpleJob对应的实现类:
@Component
public class SimpleJobA implements SimpleJob{
@Override
public void execute(ShardingContext context) {
System.out.println(String.format("------SimpleJobA: Thread ID: %s, 任务总片数: %s, 当前分片项: %s", Thread.currentThread().getId(),context.getShardingTotalCount(),context.getShardingItem()));
}
}
数据流作业实现类:DataFlowJobEven和DataFlowJobOdd分别查询数据库行业表Industry的id奇偶记录并输出:
@Component
public class DataFlowJobEven implements DataflowJob<Industry>{
@Autowired
private IndustryService industryService;
@Resource
private IndustryDAO industry;
@Override
public List<Industry> fetchData(ShardingContext context) {
System.out.println(String.format("------DataFlowJobEven: Thread ID: %s, 任务总片数: %s, 当前分片项: %s", Thread.currentThread().getId(),context.getShardingTotalCount(),context.getShardingItem()));
List<Industry> retList = industry.queryListEven();
return retList;
}
@Override
public void processData(ShardingContext context, List<Industry> list) {
System.out.println("Even count: " + list.size());
for(Industry in : list) {
System.out.println(in.getId() + "--" +in.getName() +"--" + in.getEnname());
}
}
}
@Component
public class DataFlowJobOdd implements DataflowJob<Industry>{
@Resource
private IndustryService industryService;
@Resource
private IndustryDAO industry;
@Override
public List<Industry> fetchData(ShardingContext context) {
System.out.println(String.format("------DataFlowJobOdd: Thread ID: %s, 任务总片数: %s, 当前分片项: %s", Thread.currentThread().getId(),context.getShardingTotalCount(),context.getShardingItem()));
System.out.println(industry);
List<Industry> retList = industry.queryListOdd();
return retList;
}
@Override
public void processData(ShardingContext context, List<Industry> list) {
System.out.println("Odd count: " + list.size());
for(Industry in : list) {
System.out.println(in.getId() +" --" + in.getName() +"--" + in.getEnname());
}
}
}
其中作业流的会先调用fetchData方法查询满足条件的数据,再传入processData方法中进行批量处理。
- 配置作业
关于配置文件中的注册中心zookeeper需要自行安装,单机安装也挺简单的,在此就不在说明。
文件名:elastic-job.xml。配置可以参考:elastic-job配置手册
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:reg="http://www.dangdang.com/schema/ddframe/reg"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:job="http://www.dangdang.com/schema/ddframe/job"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.dangdang.com/schema/ddframe/reg
http://www.dangdang.com/schema/ddframe/reg/reg.xsd
http://www.dangdang.com/schema/ddframe/job
http://www.dangdang.com/schema/ddframe/job/job.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 这里配置的zookeeper与elastic console有关 -->
<reg:zookeeper server-lists="192.168.7.21:3181" id="goPayCenter"
namespace="payment-ls" base-sleep-time-milliseconds="1000"
max-retries="3" />
<!-- 作业配置A --&