Elastic-job三种模式(JAVA-API实现)

Elastic-Job java-api方式实现

为什么要用定时任务?

1.数据备份每天凌晨 每天凌晨2点,因为凌晨的时候系统不是繁忙,不使用定时任务,就是用人工操作
2.心跳的监控,每隔10分钟去监听接口,是否正常,没有定时任务需要人工去查一下
3.每隔5分钟去淘宝京东抓取订单,有些卖家在不同的平台上架,总不能商家去每隔平台定时自己拉取一下吧
4.订单的支付,由于用户30分钟没有付款,自动取消该订单 是企业应用系统中必要的,是必须要的 解决掉了,大量的人力和物力 ,SpringTask 支持单点 ,不支持集群 Quartz 支持集群 但是不支持分布式不能将一个任务进行拆解 ,可以动态添加

优点:
Elastic-job 分布式集群 支持分布式 缺点不可以动态添加,将一个任务,拆分成多个独立的任务项目,由分布式的服务器分别执行某一个,或多个分片项 一个大量的任务 会进行拆解成多份进行处理 多个服务,一一承担
它有几种服务模式?
他有三种:大家在这里先记住这三种模式即可,后面我会为大家一一讲解

1. Simple(简单) 简单模式
2. DataFlow(流) 流模式
3. Script (脚本) 脚本模式

什么是分布式调度?

分布式处理请求中的一部分调度,就是不同的请求过来,分给不同的服务进行助理,我有服务1和服务2,就是这两个服务同时提供服务

什么是分片?

一个任务,拆分成多个独立的任务项,每个服务获得一个或多个分片项 例如两台服务器,每台服务器执行50%
,基数偶数拆分,如果听不懂的话,看如下图
有两个服务,分片分两片,一个服务执行一片,就相当于把一个任务拆分成两份,查询到100条数据,也就是拆分成两份,一个人处理50个数据
在这里插入图片描述

如果分10片会怎么样拆分?
如下图:
在这里插入图片描述
如果分9片会怎么样那?
在这里插入图片描述
看图可理解到他的分片机制,是如何分片的,还有一个如果分一片,两个服务会怎么样那?
在这里插入图片描述

由上图得出,两个相同的服务,执行一个任务的时候分一片处理,另一个则会进行等待,等待服务A宕机,他会失效转移,将A服务没有执行完,或者A服务该执行的,他会代替A服务去执行,这样就可以实现高可用

Elastic-job 不直接提供数据处理 ,只提供分片,开发者自行处理
作业高可用:
部署多台定时任务,分片总数设置为1,多于1台服务器执行作业,1主n从,执行服务器崩溃后,等待的服务器将启动,执行下次任务,1分片 多个服务 abc a能拿到 bc等待 a挂机 bc继续去执行,失效转移 复活之后 恢复到原来的

前提依赖于zookeeper,大家可以在网上找一下安装zookeeper的帖子,自行安装

引入maven依赖:

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

Simple模式:

Simple类型作业意为简单实现,未经任何封装的类型。需实现SimpleJob接口。该接口仅提供单一方法用于覆盖,此方法将定时执行。与Quartz原生接口相似,但提供了弹性扩缩容和分片等功能。

JAVA-API方式使用 简单模式:称之为简单模式,也就是和普通定时任务一样的,根据分片处理业务

/**
 * 任务类
 */
public class MySimpleJob implements SimpleJob {
    /**
     * 分片上下文
     * @param shardingContext
     */
    @Override
    public void execute(ShardingContext shardingContext) {
        LocalDateTime localDateTime=LocalDateTime.now();
        System.out.println(localDateTime+"我是分片项:"+shardingContext.getShardingItem()+
                "===>定时分片总数:"+shardingContext.getShardingTotalCount());
        switch (shardingContext.getShardingItem()) {
            case 0:
                System.out.println("京东订单抓取");
                break;
            case 1:
                System.out.println("淘宝订单抓取");
                break;
        }
    }
}
  /**
     * 注册中心
     * @return
     */
    public  static CoordinatorRegistryCenter zkCenter(){
        ZookeeperConfiguration zookeeperRegistryCenter=
                new ZookeeperConfiguration("39.102.123.141:2181,39.102.123.141:2182,39.102.123.141:2183",
                "elastic-simple-job");
        CoordinatorRegistryCenter coordinatorRegistryCenter=
                new ZookeeperRegistryCenter(zookeeperRegistryCenter);
        coordinatorRegistryCenter.init();
        return coordinatorRegistryCenter;
    }


    /**
     * Job核心配置类
     * @return
     */
    public static LiteJobConfiguration simpleConfiguration(){
        //核心配置
        JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
                .newBuilder("my-simple-job",
                        "0/10 * * * * ?",
                        2).build();
        //核心类型配置
        JobTypeConfiguration jobTypeConfiguration=
                new SimpleJobConfiguration(
                        jobCoreConfiguration,
                        MySimpleJob.class.getCanonicalName());
        LiteJobConfiguration liteJobConfiguration=LiteJobConfiguration.newBuilder(jobTypeConfiguration)
                .overwrite(true)
                .build();

        return liteJobConfiguration;
    }

运行:

  System.out.println("=======>START Job<=======");
  new JobScheduler(zkCenter(), simpleConfiguration()).init();
  System.out.println("=======>STOP Job<=======");

结果:

2020-12-29T14:14:56.166我是分片项:1===>定时分片总数:2
淘宝订单抓取
2020-12-29T14:14:56.166我是分片项:0===>定时分片总数:2
京东订单抓取
2020-12-29T14:15:05.658我是分片项:0===>定时分片总数:2
京东订单抓取
2020-12-29T14:15:05.659我是分片项:1===>定时分片总数:2
淘宝订单抓取

两个服务的话,是拆开的
运行结果如下
服务A执行0 服务B执行1

DataFlow模式:

DataFlow流模式,为什么称之为流模式,例如我要去根据我的订单有100个,一次只能抓取10个,两个分片,那么请看下图:
在这里插入图片描述
上图一个负责抓取数据,一个负责处理数据,一次抓取10条,这样反复循环,直到抓取完毕,等下次定时任务启动在这样反复处理数据
代码:

public class MyDataFlowJob implements DataflowJob<Order> {
    List<Order> list=new ArrayList<>();
    {
        for (int i = 0; i < 100; i++) {
            Order order=new Order();
            order.setOrderId(i);
            order.setStatus("0");
            list.add(order);
        }
    }


    /**
     * 抓取数据
     * @param shardingContext
     * @return
     */
    @Override
    public List<Order> fetchData(ShardingContext shardingContext) {
        List<Order> collect = list.stream().filter(o -> o.getStatus() .equals("0") )
                .filter(id -> id.getOrderId() % shardingContext.getShardingTotalCount() == shardingContext.getShardingItem())
                .collect(Collectors.toList());
        List<Order> orders=null;
        if(!collect.isEmpty()){
            orders = collect.subList(0, 10);
        }
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        LocalDateTime localDateTime=LocalDateTime.now();
        System.out.println(localDateTime+" 我是分片项:"+shardingContext.getShardingItem()
                +" ====>定时分片总数"+shardingContext.getShardingTotalCount()
                +" 我抓取的数据是:"+orders);
        return orders;
    }

    /**
     * 处理数据
     * @param shardingContext
     * @param data
     */
    @Override
    public void processData(ShardingContext shardingContext, List<Order> data) {
        //更改订单状态
        data.forEach(s->s.setStatus("1"));
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LocalDateTime localDateTime=LocalDateTime.now();
        System.out.println(localDateTime+
                " 我是分片项:"+shardingContext.getShardingItem()
                +" 我正在处理数据!!"
        );

    }
}

注册中心

/**
     * 注册中心
     * @return
     */
    public  static CoordinatorRegistryCenter zkCenter(){
        ZookeeperConfiguration zookeeperRegistryCenter=
                new ZookeeperConfiguration("39.102.123.148:2181,39.102.123.148:2182,39.102.123.148:2183",
                "elastic-simple-job");
        CoordinatorRegistryCenter coordinatorRegistryCenter=
                new ZookeeperRegistryCenter(zookeeperRegistryCenter);
        coordinatorRegistryCenter.init();
        return coordinatorRegistryCenter;
    }

DataFlow的配置

 /**
     * Job核心配置类
     * @return
     */
    public static LiteJobConfiguration dataFlowConfiguration(){
        //核心配置
        JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
                .newBuilder("my-dataFlow",
                        "0/5 * * * * ?",
                        2).build();
        //核心类型配置
        JobTypeConfiguration jobTypeConfiguration=
                new DataflowJobConfiguration(
                        jobCoreConfiguration,
                        MyDataFlowJob.class.getCanonicalName(),true);
        LiteJobConfiguration liteJobConfiguration=LiteJobConfiguration.newBuilder(jobTypeConfiguration)
                .overwrite(true)
                .build();

        return liteJobConfiguration;
    }

public class ApplicationElasticJob {
    public static void main(String[] args) {
        System.out.println("=======>START Job<=======");
        new JobScheduler(zkCenter(), dataFlowConfiguration()).init();
        System.out.println("=======>STOP Job<=======");
    }

运行结果服务A

2020-12-29T15:06:34.778 我是分片项:1 ====>定时分片总数2 我抓取的数据是:[Order{orderId=1, status='0'}, Order{orderId=3, status='0'}, Order{orderId=5, status='0'}, Order{orderId=7, status='0'}, Order{orderId=9, status='0'}, Order{orderId=11, status='0'}, Order{orderId=13, status='0'}, Order{orderId=15, status='0'}, Order{orderId=17, status='0'}, Order{orderId=19, status='0'}]
2020-12-29T15:06:37.779 我是分片项:1 我正在处理数据!!
2020-12-29T15:06:40.791 我是分片项:1 ====>定时分片总数2 我抓取的数据是:[Order{orderId=21, status='0'}, Order{orderId=23, status='0'}, Order{orderId=25, status='0'}, Order{orderId=27, status='0'}, Order{orderId=29, status='0'}, Order{orderId=31, status='0'}, Order{orderId=33, status='0'}, Order{orderId=35, status='0'}, Order{orderId=37, status='0'}, Order{orderId=39, status='0'}]
2020-12-29T15:06:43.791 我是分片项:1 我正在处理数据!!
2020-12-29T15:06:46.881 我是分片项:1 ====>定时分片总数2 我抓取的数据是:[Order{orderId=41, status='0'}, Order{orderId=43, status='0'}, Order{orderId=45, status='0'}, Order{orderId=47, status='0'}, Order{orderId=49, status='0'}, Order{orderId=51, status='0'}, Order{orderId=53, status='0'}, Order{orderId=55, status='0'}, Order{orderId=57, status='0'}, Order{orderId=59, status='0'}]
2020-12-29T15:06:49.882 我是分片项:1 我正在处理数据!!
2020-12-29T15:07:13.438 我是分片项:1 ====>定时分片总数2 我抓取的数据是:[Order{orderId=61, status='0'}, Order{orderId=63, status='0'}, Order{orderId=65, status='0'}, Order{orderId=67, status='0'}, Order{orderId=69, status='0'}, Order{orderId=71, status='0'}, Order{orderId=73, status='0'}, Order{orderId=75, status='0'}, Order{orderId=77, status='0'}, Order{orderId=79, status='0'}]
2020-12-29T15:07:16.439 我是分片项:1 我正在处理数据!!

服务B

2020-12-29T15:06:33.566 我是分片项:0 ====>定时分片总数2 我抓取的数据是:[Order{orderId=0, status='0'}, Order{orderId=2, status='0'}, Order{orderId=4, status='0'}, Order{orderId=6, status='0'}, Order{orderId=8, status='0'}, Order{orderId=10, status='0'}, Order{orderId=12, status='0'}, Order{orderId=14, status='0'}, Order{orderId=16, status='0'}, Order{orderId=18, status='0'}]
2020-12-29T15:06:36.570 我是分片项:0 我正在处理数据!!
2020-12-29T15:06:39.736 我是分片项:0 ====>定时分片总数2 我抓取的数据是:[Order{orderId=20, status='0'}, Order{orderId=22, status='0'}, Order{orderId=24, status='0'}, Order{orderId=26, status='0'}, Order{orderId=28, status='0'}, Order{orderId=30, status='0'}, Order{orderId=32, status='0'}, Order{orderId=34, status='0'}, Order{orderId=36, status='0'}, Order{orderId=38, status='0'}]
2020-12-29T15:06:42.736 我是分片项:0 我正在处理数据!!
2020-12-29T15:06:46.787 我是分片项:0 ====>定时分片总数2 我抓取的数据是:[Order{orderId=40, status='0'}, Order{orderId=42, status='0'}, Order{orderId=44, status='0'}, Order{orderId=46, status='0'}, Order{orderId=48, status='0'}, Order{orderId=50, status='0'}, Order{orderId=52, status='0'}, Order{orderId=54, status='0'}, Order{orderId=56, status='0'}, Order{orderId=58, status='0'}]
2020-12-29T15:06:49.787 我是分片项:0 我正在处理数据!!

Scirpt模式

也就是运维定时执行脚本命令的时候

  /**
     * Job核心配置类
     * @return
     */
    public static LiteJobConfiguration scriptConfiguration(){
        //核心配置
        JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
                .newBuilder("my-script",
                        "0/5 * * * * ?",
                        2).build();
        //核心类型配置
        JobTypeConfiguration jobTypeConfiguration=new ScriptJobConfiguration(jobCoreConfiguration, "C:\\Users\\capitek\\Desktop\\test.cmd");
        LiteJobConfiguration liteJobConfiguration=LiteJobConfiguration.newBuilder(jobTypeConfiguration)
                //.overwrite(true)
                .build();

        return liteJobConfiguration;
    }

运行

new JobScheduler(zkCenter(), scriptConfiguration()).init();

运行脚本定时执行
脚本内容

echo 我是CMD脚本,我的作业信息是: %1,%2,%3,%4,%5,%6

运行结果:

E:\code\Elastic-Job-Quartz>echo 我是CMD脚本,我的作业信息�? {"jobName":"my-script","taskId":"my-script@-@0,1@-@READY@-@192.168.100.1@-@14276","shardingTotalCount":2,"jobParameter":"","shardingItem":1}, 
我是CMD脚本,我的作业信息�? {"jobName":"my-script","taskId":"my-script@-@0,1@-@READY@-@192.168.100.1@-@14276","shardingTotalCount":2,"jobParameter":"","shardingItem":1},

E:\code\Elastic-Job-Quartz>echo 我是CMD脚本,我的作业信息�? {"jobName":"my-script","taskId":"my-script@-@0,1@-@READY@-@192.168.100.1@-@14276","shardingTotalCount":2,"jobParameter":"","shardingItem":0}, 
我是CMD脚本,我的作业信息�? {"jobName":"my-script","taskId":"my-script@-@0,1@-@READY@-@192.168.100.1@-@14276","shardingTotalCount":2,"jobParameter":"","shardingItem":0},

这就是JAVA-API启动方式 这三种后续整合Spring

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值