最近项目中需要做定时跑批任务,因为是SOA的项目,spring自带的单节点定时任务已经不能满足任务,为了快速上线,选择了当当网开元的elasticjob lite版本。
其实使用很简单,几个简单配置就ok了。
项目中使用的是simpleJob,我就简单把代码贴一下吧。
项目引入elasticjob大致以下几个步骤:
1.pom文件引入相关的依赖
2.编写我们的定时任务
3.编写配置文件
4.配置部署job的管理平台
下面开始贴代码:
第一步:pom引入配置文件
<!-- 当当网分布式定时任务组件 -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
</exclusion>
</exclusions>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-common-restful</artifactId>
<version>2.1.5</version>
</dependency>
<!-- 当当网分布式定时任务组件 -->
因为是dubbo项目,exclusions主要是解决dubbo与elasticJob在链接,操作zookeeper时的jar冲突问题,这个看版本排除即可。
排除方法可以用STS的如下视图排查:
第二步:编写我们的定时任务:
@Data
public class SchoolVoteTask implements SimpleJob {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Value("${test.name}")
private String name;
@Autowired
private VoteUserVideoInfoService voteVideoService;
@Override
public void execute(ShardingContext shardingContext) {
// 1.当分片数为1时,在同一个zookepper和jobname情况下,多台机器部署了Elastic
// job时,只有拿到shardingContext.getShardingItem()为0的机器得以执行,其他的机器不执行
// 2.当分片数大于1时,假如有3台服务器,分成10片,则分片项分配结果为服务器A=0,1,2;服务器B=3,4,5;服务器C=6,7,8,9。此时每台服务器可根据拿到的shardingItem值进行相应的处理,
// 举例场景:
// 假如job处理数据库中的数据业务,方法为:A服务器处理数据库中Id以0,1,2结尾的数据,B处理数据库中Id以3,4,5结尾的数据,C处理器处理6,7,8,9结尾的数据,合计处理0-9为全部数据
// 如果服务器C崩溃,Elastic
// Job自动进行进行失效转移,将C服务器的分片转移到A和B服务器上,则分片项分配结果为服务器A=0,1,2,3,4;服务器B=5,6,7,8,9
// 此时,A服务器处理数据库中Id以0,1,2,3,4结尾的数据,B处理数据库中Id以5,6,7,8,9结尾的数据,合计处理0-9为全部数据.
int shardingTotalCount = shardingContext.getShardingTotalCount();
String shardingParameter = shardingContext.getShardingParameter();
int shardingItem = shardingContext.getShardingItem();
switch (shardingItem) {
case 0:
try {
expiredVote();
} catch (ParseException e) {
e.printStackTrace();
}
break;
case 1:
System.out.println("OrderTask-1-" + shardingTotalCount + shardingParameter);
break;
case 2:
System.out.println("OrderTask-2-" + shardingTotalCount + shardingParameter);
break;
default:
break;
}
}
private void expiredVote() throws ParseException {
VoteUserVideoInfoRequestDTO request = new VoteUserVideoInfoRequestDTO();
request.setAuditState("S");
request.setFlag("1");
request.setVoteState("1");
List<VoteUserVideoInfoResponseDTO> list = voteVideoService.findMutil(request);
List<Long> idslst = new ArrayList<Long>();
for (int i = 0; i < list.size(); i++) {
VoteUserVideoInfoResponseDTO dto = list.get(i);
Date auditDate = dto.getAuditTime();
String auditDateStr = sdf.format(auditDate);
auditDate = sdf.parse(auditDateStr);
Date currentDate = new Date();
String currentDateStr = sdf.format(currentDate);
currentDate = sdf.parse(currentDateStr);
int a = (int) ((currentDate.getTime() - auditDate.getTime()) / (1000 * 3600 * 24));
if (a > 7) {
// System.out.println(dto);
idslst.add(dto.getId());
}
}
if (idslst.size() != 0) {
Long[] ids = new Long[idslst.size()];
for (int i = 0; i < idslst.size(); i++) {
ids[i] = idslst.get(i);
}
int result = voteVideoService.expiredVote(ids);
System.out.println("result=" + result);
}
}
}
因为我们项目只需要简单的定时任务,只要实现当当的SimpleJob接口即可。
其分片功能可以通过ShardingContext获取相关参数,比如:
int shardingTotalCount = shardingContext.getShardingTotalCount();
String shardingParameter = shardingContext.getShardingParameter();
int shardingItem = shardingContext.getShardingItem();
shardingItem 便是分片的序号,然后可以根据不同的值,做相应的处理即可。
关于分片处理,要知道下面几点:
1.当分片数为1时,在同一个zookepper和jobname情况下,多台机器部署了Elasticjob时,只有拿到shardingContext.getShardingItem()为0的机器得以执行,其他的机器不执行
2.当分片数大于1时,假如有3台服务器,分成10片,则分片项分配结果为服务器A=0,1,2;服务器B=3,4,5;服务器C=6,7,8,9。此时每台服务器可根据拿到的shardingItem值进行相应的处理,举例场景:
假如job处理数据库中的数据业务,方法为:A服务器处理数据库中Id以0,1,2结尾的数据,B处理数据库中Id以3,4,5结尾的数据,C处理器处理6,7,8,9结尾的数据,合计处理0-9为全部数据
如果服务器C崩溃,ElasticJob自动进行进行失效转移,将C服务器的分片转移到A和B服务器上,则分片项分配结果为服务器A=0,1,2,3,4;服务器B=5,6,7,8,9,此时,A服务器处理数据库中Id以0,1,2,3,4结尾的数据,B处理数据库中Id以5,6,7,8,9结尾的数据,合计处理0-9为全部数据.
第三步:编写我们的配置文件:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:reg="http://www.dangdang.com/schema/ddframe/reg"
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-4.3.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-4.3.xsd " default-lazy-init="false">
<!--配置作业注册中心 -->
<!--
serverLists=10.3.142.107:2181,10.3.142.107:2182,106.3.14.107:2183
namespace=elastic-job-example
baseSleepTimeMilliseconds=1000
maxSleepTimeMilliseconds=3000
maxRetries=3
-->
<reg:zookeeper id="regCenter"
server-lists="${elastic.job.zk.address}"
namespace="${elastic.job.namespace}"
base-sleep-time-milliseconds="${elastic.job.baseSleepTimeMilliseconds}"
max-sleep-time-milliseconds="${elastic.job.maxSleepTimeMilliseconds}"
max-retries="${elastic.job.maxRetries}"
session-timeout-milliseconds="${elastic.job.sessionTimeoutMilliseconds}"
connection-timeout-milliseconds="${elastic.job.connectionTimeoutMilliseconds}" />
<!-- 配置作业-->
<job:simple id="schoolVoteTask"
class="com.ddc.mcn.service.task.SchoolVoteTask"
registry-center-ref="regCenter"
cron="0/10 * * * * ?"
sharding-total-count="3"
sharding-item-parameters="0=A,1=B,2=C"
event-trace-rdb-data-source="dataSource"
overwrite="true" />
<!--
<job:dataflow id="orderDataFlowTask"
class="com.framework.core.job.OrderDataFlowTask"
streaming-process="false"
registry-center-ref="regCenter"
cron="0/10 * * * * ?"
sharding-total-count="3"
sharding-item-parameters="0=A,1=B,2=C" />
-->
</beans>
这里面简单的做个说明步骤:
1.引入job的schema,
xmlns:reg="http://www.dangdang.com/schema/ddframe/reg"
xmlns:job="http://www.dangdang.com/schema/ddframe/job"
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
2.注册zk配置中心
3.注册我们的作业任务
第四步:配置job的管理平台
这个很简单,只要在官网上下载elastic-job-lite,然后执行bin中的start.bat(window环境)或者start.sh(linux环境)即可。
端口8899,登录账号,在conf下的文件中,可以修改等着账号信息的
在全部配置中添加zk,连接上以后,在作业操作的作业维度中,就可以看到我们的定时任务了,然后可以在里面做一些我们需要的修改,都是立即生效的(心跳时间不算哈)
怎么样,很简单吧。