springboot2 + Elastic-job

项目里面,之前一直使用的是 quartz 。用的也很稳定,也有一段时间了,但是 elastic-job,更加强大

官网:http://elasticjob.io/index_zh.html

elastic-job 有2种 实现方式,有2个独立的子项目,一个是 elastic-job-lite 一个是 elastic-job-cloud,
个人简单的理解呢就是:

elastic-job-lite

  去中心化,只是依赖zookeeper。适合JAVA项目这种,任务嵌套在业务代码里面。使用也是比较方便的

elastic-job-cloud

   私有云平台的方式提供集资源、调度以及分片为一体的全量级解决方案,依赖Mesos和Zookeeper。再简单的说,就是要写好任务,打好包,然后发送到云平台去。不太适合嵌套在项目里面。

我这里只尝试了elastic-job-lite 方式。

配置

在使用之前,最好是先看看官网的配置文档,然后再去找点别人的经验。事半功倍。
文档地址:http://elasticjob.io/docs/elastic-job-lite/02-guide/config-manual/
在这里插入图片描述
里面的配置说的很详细,而且能够了解清楚,有哪些功能

项目搭建

新建一个 maven 工程。
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>cat.luo</groupId>
  <artifactId>cat_elastic_job</artifactId>
  <version>0.0.1-SNAPSHOT</version>
	<name>cat_elastic_job</name>
	<description>cat_dubbo_client</description>
	<packaging>jar</packaging>
	<url>http://maven.apache.org</url>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.9.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!-- spring boot aop starter依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

		<dependency>
		    <groupId>com.dangdang</groupId>
		    <artifactId>elastic-job-lite-spring</artifactId>
		    <version>2.1.5</version>
		</dependency>

	</dependencies>

	<build>
		<finalName>cat_elastic_job</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
			</plugin>

		</plugins>
	</build>
</project>


application.properties

spring.application.index=true

spring.application.name=cat_elastic_job
spring.jmx.default-domain=cat_elastic_job
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.default-property-inclusion=non_null
spring.jackson.time-zone=GMT+8

#security.user.name=daiming
#security.user.password=123456
#security.basic.enabled=false

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

spring.http.multipart.maxFileSize=30Mb
spring.http.multipart.maxRequestSize=30Mb

home.path=classpath:config
#home.path=/usr/local/tomcat/tomcat8081_smk_mall/config

logging.config=${home.path}/logback-spring.xml
logging.level.com=debug

#actuator authentication config
management.security.enabled=false

#properties active
#spring.profiles.active=tomcat
#spring.profiles.include=dev,db,kafka

server.port=8080
# the servlet path, defaults to '/'
server.servlet.context-path=/cat_elastic_job
# session timeout in seconds
server.session.timeout=30*60
server.tomcat.uri-encoding=UTF-8
server.connection-timeout=20000
server.tomcat.accept-count=800
server.tomcat.max-connections=500
server.tomcat.max-threads=1000

#server.address= # bind to a specific NIC
#server.tomcat.access-log-pattern= # log pattern of the access log
#server.tomcat.access-log-enabled=false # is access logging enabled
#server.tomcat.protocol-header=x-forwarded-proto # ssl forward headers
#server.tomcat.remote-ip-header=x-forwarded-for
#server.tomcat.basedir=/tmp # base dir (usually not needed, defaults to tmp)
#server.tomcat.background-processor-delay=30; # in seconds

server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.file-date-format=yyyy-MM-dd
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.suffix=.log



重点。新建一个任务处理class,elastic-Job提供Simple、Dataflow和Script 3种作业类型。每种作业类型有不同的功能,可以自行去查询
我使用的是简单的 SimpleJob

package com.jobs;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;


public class CatJob implements SimpleJob {

	public void execute(ShardingContext shardingContext) {
		int i = shardingContext.getShardingItem();
		switch (i) {
        case 0: 
           System.out.println("分片:"+i+",分片对应自定义值:"+shardingContext.getShardingParameter());
            break;
        case 1: 
        	 System.out.println("分片:"+i+",分片对应自定义值:"+shardingContext.getShardingParameter());
            break;
        case 2: 
        	 System.out.println("分片:"+i+",分片对应自定义值:"+shardingContext.getShardingParameter());
            break;
        default:
        	System.out.println("分片异常");
        	
    }
		
	}

}


配置任务调度逻辑
官方给出了2中实现方式,一种是API方式,另外一种是 xml 方式。
按照道理来说,我使用了 springboot项目,就应该是使用API 方式来做的,可事实发现,还是使用XML 方式来做更加清晰简单和方便,而且还可以很方便更新和修改任务。

定义一个jobs.xml

 <?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: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
                        ">
    <!--配置作业注册中心 -->
    <reg:zookeeper id="regCenter" server-lists="192.168.23.212:2181" namespace="test" base-sleep-time-milliseconds="1000"
                   max-sleep-time-milliseconds="3000" max-retries="3" />

    <!-- 配置作业 下面的TestJob就是我们刚才新建的测试类-->
    <job:simple id="testJob" class="com.jobs.CatJob"
                registry-center-ref="regCenter"  cron="15/0 * * * * ?"
                sharding-item-parameters="0=A,1=B,2=C" description="这个一个定时任务" sharding-total-count="3"/>

</beans>

这个配置很简单,看了官网的文档,就很清晰的知道每个配置是什么作用的了
关键点: zookeeper 配置就不说了
sharding-total-count=“3” 分片数量,意思是你想把你的任务 拆分成几个任务。
sharding-item-parameters=“0=A,1=B,2=C” 这个配置,是根据上面的 分片数量来定义的,上面定义3,这边就是定义3个键值对,0,1,2.然后分别对应的值,是自定义的

这里的key 对应的是代码里面的 shardingContext.getShardingItem();
这里的Value对应的是 shardingContext.getShardingParameter()

根据这2个参数,我们子作业代码里面,就可以自行更具这个参数,实现作业分片运行。

定义好了 配置文件。最后是 启动类

package com;

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@Configuration
@EnableAsync
@EnableScheduling
@EnableCaching
@EnableAutoConfiguration()
@ImportResource(locations = {"classpath:config/jobs.xml"})
public class App {

	public static void main(String[] args) throws IOException {
		SpringApplication.run(App.class, args);
	}

}


这里需要引入我们刚才定义的 任务

启动执行

看结果:`
分片:0,分片对应自定义值:A
分片:1,分片对应自定义值:B
分片:2,分片对应自定义值:C

分片数量设置不正确
sharding-item-parameters=“0=A” overwrite=“true” sharding-total-count=“2”
结果:
分片:0,分片对应自定义值:A
分片:1,分片对应自定义值:null

分片设置为 0 的时候,就会抛异常。
这里说说我发现的一个坑,elastic-job 的一个坑。

    <job:simple id="testJobddddd" class="com.jobs.CatJob"
                registry-center-ref="regCenter" cron="0/6 * * * * ?"
                sharding-item-parameters="0=A,1=B,2=C" description=""  overwrite="true" sharding-total-count="0" />

我突发奇想,如果设置了分片数为 0 ,是不是就是不执行了。

启动之后报错

Caused by: java.lang.IllegalArgumentException: shardingTotalCount should larger than zero.
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
	at com.dangdang.ddframe.job.config.JobCoreConfiguration$Builder.build(JobCoreConfiguration.java:190)
	at com.dangdang.ddframe.job.util.json.AbstractJobConfigurationGsonTypeAdapter.getJobCoreConfiguration(AbstractJobConfigurationGsonTypeAdapter.java:144)
	at com.dangdang.ddframe.job.util.json.AbstractJobConfigurationGsonTypeAdapter.read(AbstractJobConfigurationGsonTypeAdapter.java:113)
	at com.dangdang.ddframe.job.util.json.AbstractJobConfigurationGsonTypeAdapter.read(AbstractJobConfigurationGsonTypeAdapter.java:46)
	at com.google.gson.Gson.fromJson(Gson.java:927)
	at com.google.gson.Gson.fromJson(Gson.java:892)
	at com.google.gson.Gson.fromJson(Gson.java:841)
	at com.google.gson.Gson.fromJson(Gson.java:813)
	at com.dangdang.ddframe.job.lite.internal.config.LiteJobConfigurationGsonFactory.fromJson(LiteJobConfigurationGsonFactory.java:79)
	at com.dangdang.ddframe.job.lite.internal.config.ConfigurationService.load(ConfigurationService.java:61)
	at com.dangdang.ddframe.job.lite.internal.schedule.SchedulerFacade.updateJobConfiguration(SchedulerFacade.java:104)
	at com.dangdang.ddframe.job.lite.api.JobScheduler.init(JobScheduler.java:105)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1819)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1762)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1690)
	... 16 common frames omitted

shardingTotalCount should larger than zero.
必须要设置大于 0

那就是不能设置0
那我就改回来,

 <job:simple id="testJobddddd" class="com.jobs.CatJob"
                registry-center-ref="regCenter" cron="0/6 * * * * ?"
                sharding-item-parameters="0=A,1=B,2=C" description=""  overwrite="true" sharding-total-count="3" />

我这里设置的 overwrite=“true” 是true.允许覆盖

可以无论我怎么去清理缓存,嘿,就是不行,一直改不了,一直都是这个错误shardingTotalCount should larger than zero.

我在试了,清理maven编译文件,清理工具,重启开发工具,电脑也重启了,就是不行。
这个时候,我想到了,这个配置应该是保存在 zookeeper 里面的。
那就是 重启zookeeper ,结果还是不行

然后再次想到 zookeeper 有本地存储。
那好,找到了zookeeper 本地存储目录,删除了整个 存储目录的文件。
再次启动项目,OK了。。。。。。。。。

好一个坑啊。

elastic-job,设置了错误的配置上去,就里面存储在 zookeeper 里面,就算项目里面改成了正确的配置,也还是无法覆盖。

只有第一次是正确的,下次才能覆盖上去,

大致猜测了其中的机制,应该先按照zookeeper 里面存储的配置启动,然后再去对比 项目里面的配置,替换。
如果 启动都没有成功,直接就失败了。

这个是一个问题。

虽然,应该不会有人这么傻傻的故意设置一个 错误的分片数 0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值