分布式定时任务之1:elasticjob配置使用

最近项目中需要做定时跑批任务,因为是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,连接上以后,在作业操作的作业维度中,就可以看到我们的定时任务了,然后可以在里面做一些我们需要的修改,都是立即生效的(心跳时间不算哈)

 

怎么样,很简单吧。

 

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
定时任务是指在预定的时间间隔或特定时间执行的任务。而分布式定时任务是指将这些任务分布到多台机器上执行,以实现更高的可靠性和可伸缩性。 Java中有多种实现定时任务分布式定时任务的方法,其中一种是使用JDK原生提供的定时任务功能。通过使用`java.util.Timer`或`java.util.concurrent.ScheduledExecutorService`类,可以在Java中创建和调度定时任务。 另一种常见的实现方式是使用Spring框架。Spring提供了丰富的定时任务支持,包括基于注解的定时任务和基于XML配置定时任务。通过使用`@Scheduled`注解,可以将方法标记为定时任务,并指定任务的执行时间间隔或特定时间点。 此外,Spring还提供了整合数据库和Redis的方式来存储和管理定时任务。通过将任务列表存储在关系型数据库或Redis中,可以实现任务的持久化和分布式管理。 对于分布式定时任务,可以使用消息队列(如RabbitMQ)来实现任务的分发和调度。通过将任务发布到消息队列中,不同的任务消费者可以从队列中获取任务并执行。这种方式可以实现任务的水平扩展和负载均衡。 另外,还有一些开源的分布式定时任务框架,如Quartz、Elastic-Job、XXL-Job等,它们提供了更丰富的功能和更灵活的配置选项。 总结起来,定时任务可以通过JDK原生的定时任务、Spring框架、数据库或Redis存储以及消息队列来实现。而分布式定时任务则可以通过使用消息队列和开源框架来实现。具体选择哪种方式取决于项目需求和技术栈的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值