elastic-job集成到springboot教程,和它的一个异常处理办法:Sharding item parameters '1' format error, should be int=xx,int=xx

先说这个Sharding item parameters ‘1‘ format error, should be int=xx,int=xx异常吧,这是在做动态添加调度任务的时候出现的,网上找了一会没有搜到任何信息,最后发现,是添加任务这个方法里有一个漏洞。

这个源码出自:

 1 private ShardingItem parse(final String shardingItemParameter, final String originalShardingItemParameters) {
 2         String[] pair = shardingItemParameter.trim().split(KEY_VALUE_DELIMITER);
 3         if (2 != pair.length) {
 4             throw new JobConfigurationException("Sharding item parameters ‘%s‘ format error, should be int=xx,int=xx", originalShardingItemParameters);
 5         }
 6         try {
 7             return new ShardingItem(Integer.parseInt(pair[0].trim()), pair[1].trim());
 8         } catch (final NumberFormatException ex) {
 9             throw new JobConfigurationException("Sharding item parameters key ‘%s‘ is not an integer.", pair[0]);
10         }
11     }

修改前代码(报这个异常的代码):

1  public void addJobScheduler(final Class<? extends SimpleJob> jobClass,
2       final String cron,
3       final int shardingTotalCount,
4       final String shardingItemParameters) {
5     JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount).shardingItemParameters(shardingItemParameters).build();
6     SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, jobClass.getCanonicalName());
7     JobScheduler jobScheduler = new JobScheduler(regCenter, LiteJobConfiguration.newBuilder(simpleJobConfig).build());
8     jobScheduler.init();
9   }

是不是发现不管你怎么设置,都给你报这个,你明明传的就不是1这个参数,还是给你报这个,问题出在build()那里,需要overwrite。修改后:

1  public void addJobScheduler(final Class<? extends SimpleJob> jobClass,
2       final String cron,
3       final int shardingTotalCount,
4       final String shardingItemParameters) {
5     JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount).shardingItemParameters(shardingItemParameters).build();
6     SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, jobClass.getCanonicalName());
7     JobScheduler jobScheduler = new JobScheduler(regCenter, LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true).build());
8     jobScheduler.init();
9   }

红色代码为修改后加的代码。

先说说这个dangdang的elastic-job,它是一个分布式任务调度插件。今天我遇到的问题就是,有部分任务,在多节点环境中,不需要每个节点执行,比如只需要一个节点(确切地说就是作业分片总数=1)上运行的任务,这时候elastic-job就是个不错的选择,它可以很灵活的配置作业分片总数等。它的官方文档,链接指向配置说明:http://elasticjob.io/docs/elastic-job-lite/02-guide/config-manual/

那么spring boot中如何集成进它。需要的一个前提条件是zookeeper服务,这个一般项目里都会用到,你只需要连就好了,如果dev或者你们还没用上,可以找个教程安装一下。链接指向在 CentOS7 上安装 Zookeeper服务 。

然后.propertis配置文件(yml类同):

regCenter.serverList=10.0.30.140:2181
regCenter.namespace=elastic-job

simpleJob.cron=0/5 * * * * ?
# 作业分片总数,设为1只在一个节点执行
simpleJob.shardingTotalCount=1
simpleJob.shardingItemParameters=0=A,1=B,2=C

当然,pom中需要引入elastic-job:

<dependency>
    <artifactId>elastic-job-common-core</artifactId>
    <groupId>com.dangdang</groupId>
    <version>${elastic-job.version}</version>
  </dependency>
  <dependency>
    <artifactId>elastic-job-lite-core</artifactId>
    <groupId>com.dangdang</groupId>
    <version>${elastic-job.version}</version>
  </dependency>
  <dependency>
    <artifactId>elastic-job-lite-spring</artifactId>
    <groupId>com.dangdang</groupId>
    <version>${elastic-job.version}</version>
  </dependency>
  <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-test</artifactId>
    <version>${curator.version}</version>
  </dependency>

本示例代码用到的版本是:

<elastic-job.version>2.1.5</elastic-job.version>
    <curator.version>2.10.0</curator.version>

连接zookeeper注册中心:

import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author binhy
 *@date 2019-1-22
 */
@Configuration
@ConditionalOnExpression("‘${regCenter.serverList}‘.length() > 0")
public class RegistryCenterConfig {

  @Bean(initMethod = "init")
  public ZookeeperRegistryCenter regCenter(@Value("${regCenter.serverList}") final String serverList, @Value("${regCenter.namespace}") final String namespace) {
    return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
  }
}

然后做一个任务信息持久化:

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.event.rdb.JobEventRdbConfiguration;

/**
 * @author binhy
 *@date 2019-1-22
 */
@Configuration
public class JobEventConfig {

  @Resource
  private DataSource dataSource;

  @Bean
  public JobEventConfiguration jobEventConfiguration() {
    return new JobEventRdbConfiguration(dataSource);
  }
}

当你最后运行后会发现你的库里多了两张表job_execution_log和job_status_trace_log他们会详细的记录你的任务执行信息,包括执行ip,开始结束时间等,还是非常不错的。

然后需要一个任务管理类,初始化一些任务,我这里把动态添加任务的方法也写在了这里。因为这种形式需要你一个任务写一个配置和类去实现。动态添加会省很多事。

import com.goopal.exdata.dangdang.DemoJob;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;

/**
 * @author binhy
 * @date 2019-1-22
 */
@Configuration
public class SimpleJobConfig {

  @Resource
  private ZookeeperRegistryCenter regCenter;

  @Resource
  private JobEventConfiguration jobEventConfiguration;

  @Bean
  public SimpleJob simpleJob() {
    return new DemoJob();
  }

  @Bean(initMethod = "init")
  public JobScheduler simpleJobScheduler(final SimpleJob simpleJob, @Value("${simpleJob.cron}") final String cron, @Value("${simpleJob.shardingTotalCount}") final int shardingTotalCount,
      @Value("${simpleJob.shardingItemParameters}") final String shardingItemParameters) {
    return new SpringJobScheduler(simpleJob, regCenter, getLiteJobConfiguration(simpleJob.getClass(), cron, shardingTotalCount, shardingItemParameters), jobEventConfiguration);
  }

  private LiteJobConfiguration getLiteJobConfiguration(final Class<? extends SimpleJob> jobClass, final String cron, final int shardingTotalCount, final String shardingItemParameters) {
    return LiteJobConfiguration.newBuilder(new SimpleJobConfiguration(JobCoreConfiguration.newBuilder(
        jobClass.getName(), cron, shardingTotalCount).shardingItemParameters(shardingItemParameters).build(), jobClass.getCanonicalName())).overwrite(true).build();
  }

  /**
   * 动态添加
   * @param jobClass
   * @param cron
   * @param shardingTotalCount
   * @param shardingItemParameters
   */
  public void addJobScheduler(final Class<? extends SimpleJob> jobClass,
      final String cron,
      final int shardingTotalCount,
      final String shardingItemParameters) {
    JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder(jobClass.getName(), cron, shardingTotalCount).shardingItemParameters(shardingItemParameters).build();
    SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, jobClass.getCanonicalName());
    JobScheduler jobScheduler = new JobScheduler(regCenter, LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true).build());
    jobScheduler.init();
  }
}

到这里,你在配置文件中配置的定时任务就已经可以在多节点环境中,仅在1个节点执行了。需要添加更多的不同cron的任务,只需要在代码业务逻辑处调用即可。如:

 @Autowired
  private  SimpleJobConfig simpleJobConfig;
  @Override
  public void run(ApplicationArguments args) throws Exception {

    simpleJobConfig.addJobScheduler(AnalysisData.class,"0/3 * * * * ?",3,"0=A,1=B,2=C");//0=A,1=B,2=C
  }

如果有帮助到你,给我点个赞哦~

elastic-job集成到springboot教程,和它的一个异常处理办法:Sharding item parameters '1' format error, should be int=xx,int=xx

原文地址:https://www.cnblogs.com/MyOceansWeb/p/10306702.html

时间: 2024-10-11 10:21:48

elastic-job集成到springboot教程,和它的一个异常处理办法:Sharding item parameters '1' format error, should be int=xx,int=xx的相关文章

移动应用开发测试工具Bugtags集成和使用教程【转载】

前段时间,有很多APP突然走红,最终却都是樱花一现.作为一个创业团队,突然爆红是非常难得的机会.然并卵,由于没有经过充分的测试,再加上用户的激增,APP闪退.服务器数据异常等问题就被暴露出来,用户的流失是必然的. 一款成功的APP,测试是必不可少的环节.如果没有充足的测试就贸然上线,必然会损失一部分本来可以成为铁杆粉丝的用户,而且,非常不利于APP的推广. 测试上遇到的问题 测试是干嘛的呢?简单来说,就是找茬的!测试发现的bug会提交到一个任务管理系统中,我们解决完bug之后,会在任务管理系统中

「Jenkins+Git+Maven+Shell+Tomcat持续集成」经典教程

Jenkins 是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变得可能.现在软件开发追求的是效率以及质量,Jenkins使得自动化成为可能! 亮点 采用shell自定义脚本,控制集成部署环境更加方便灵活 精简war包中的lib包,常驻tomcat里,减少war包传输时间 Jenkins 用户权限管理,不让淘气鬼乱动 构建失败发邮件通知相关人员解决 自动按天备份war包,Jenkins配置备份以及版本控制化 环境 Ubuntu 14.10 (GNU/Linux 3.16.0-

DuiVision开发教程(2)-如何写一个简单的界面程序

基于DuiVision界面库开发的界面程序主要包括如下几部分内容: 1.资源定义,包括图片资源.各个窗口界面的xml定义文件 2.事件处理类代码,用于处理界面响应消息 3.其他业务逻辑代码 下面举例说明如何写一个简单的界面程序. 第一步:使用VC向导创建一个有两个tab页面的DuiVision工程 向导生成的解决方案文件如下: 默认有两个工程,分别是DuiVision库和应用程序工程.自动生成的代码目录中bin目录下的内容那个如下,bkimg目录存放窗口背景图片,skins目录存放图片资源,xm

【全网最全的博客美化系列教程】07.添加一个分享的按钮吧

全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添加一只萌萌哒的小仓鼠 [全网最全的博客美化系列教程]04.访客量统计的实现 [全网最全的博客美化系列教程]05.公告栏个性时间显示的实现 [全网最全的博客美化系列教程]06.推荐和反对炫酷样式的实现 [全网最全的博客美化系列教程]07.添加一个分享的按钮吧 [全网最全的博客美化系列教程]08.自定义

企业级 SpringBoot 教程 (十一)springboot集成swagger2,构建优雅的Restful API

swagger,中文"拽"的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api,简单优雅帅气,正如它的名字. 一.引入依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <vers

企业级 SpringBoot 教程 (十三)springboot集成spring cache

本文介绍如何在springboot中使用默认的spring cache, 声明式缓存 Spring 定义 CacheManager 和 Cache 接口用来统一不同的缓存技术.例如 JCache. EhCache. Hazelcast. Guava. Redis 等.在使用 Spring 集成 Cache 的时候,我们需要注册实现的 CacheManager 的 Bean. Spring Boot 为我们自动配置了 JcacheCacheConfiguration. EhCacheCacheCo

企业级 SpringBoot 教程 (十二)springboot集成apidoc

首先声明下,apidoc是基于注释来生成文档的,它不基于任何框架,而且支持大多数编程语言,为了springboot系列的完整性,所以标了个题. 一.apidoc简介 apidoc通过在你代码的注释来生成api文档的.它对代码没有侵入性,只需要你写好相关的注释即可,并且它仅通过写简单的配置就可以生成高颜值的api接口页面.它基于node.js,所以你需要安装node.js环境.node.js安装.这里就不介绍. 二.准备工作 安装完node.js安装api.doc 通过命令安装: npm inst

转 springboot 教程

转 Spring Boot 揭秘与实战 系列 发表于 2016-12-21 | Spring框架 | SpringBoot 文章目录 1. 快速上手篇 2. 数据存储篇 3. 数据缓存篇 4. 日志框架篇 5. 配置文件篇 6. 服务器篇 7. 消息队列篇 8. 实用技术篇 9. 发布与部署 10. 应用监控篇 11. 源码分析篇 12. 附录 13. 源代码 <Spring Boot 揭秘与实战>系列,汇总文集. 快速上手篇 Spring Boot 揭秘与实战(一) 快速上手 数据存储篇 S

iOS App集成Apple Pay教程(附示例代码)

苹果在本周一发布了iOS 8.1版本,并正式开放了Apple Pay支付系统.Apple Pay是一个基于NFC的支付系统,不久将被数以万计的线下零售商店予以支持.即便这项科技并不是彻底的突破性进展,但它足以推动许多公司和零售商来支持这种支付方式,并成为苹果又一项成功的投资. Apple Pay还给开发者带来了处理支付的新渠道,用户将期望在应用中使用它,因为它将验证和交易极端简化,仅需手指轻轻一触即可完成,如果应用里面有涉及到交易,开发者很有必要集成Apple Pay.那么如何将Apple Pa