分布式定时任务调度框架

1. 分布式任务调度

  • 在系统需要运行大量耗时定时任务的场景下,单使用类似 Quartz 或者 spring task 等定时任务框架无法满足对并发处理性能、监控管理及运维拓展的要求。
  • 此时,定时任务主要面临以下几个新问题:
    1、多节点重复执行某一任务;
    2、大量的任务管理困难;
    3、某些大型任务耗时超长,需要切分给多台机器并行执行。
  • 如果仅仅面向解决第一个问题,我们可以借助分布式锁,来规避节点的执行难题。
  • 这里介绍两个框架 elastic-job 和 xxl-job ;

在这里插入图片描述
区别:

  • X-Job 侧重的业务实现的简单和管理的方便,学习成本简单,失败策略和路由策略丰富。推荐使用在“用户基数相对少,服务器数量在一定范围内,任务数量多”的情景下使用
  • E-Job 关注的是数据,增加了弹性扩容和数据分片的思路,以便于更大限度的利用分布式服务器的资源。但是学习成本相对高些, 推荐在“数据量庞大,且部署服务器数量较多”时使用。

2. E-Job 分布式调度

  • Elastic-Job 是一个分布式调度解决方案,由两个相互独立的子项目 Elastic-Job-Lite 和Elastic-Job-Cloud 组成。Elastic-Job-Lite 定位为轻量级无中心化解决方案,使用 jar 包的形式提供分布式任务的协调服务;
  • 基于 quartz 定时任务框架为基础的,因此具备 quartz 的大部分功能使用 zookeeper 做协调,调度中心,更加轻量级;
  • 支持任务的分片;
  • 支持弹性扩容,可以水平扩展,当任务再次运行时,会检查当前的服务器数量,重新分片,分片结束之后才会继续执行任务;
  • 失效转移,容错处理,当一台调度服务器宕机或者跟 zookeeper 断开连接之后,会立即停止作业,然后再去寻找其他空闲的调度服务器,来运行剩余的任务;
  • 提供运维界面,可以管理作业和注册中心;
  • E-Job的无中心化方式,非常适合整合普通业务。
  • 这里主要介绍 Elastic-Job-Lite 的去中心化解决方案。

2.1 使用场景

  • 分布式调度协调
  • 弹性扩容缩容
  • 失效转移
  • 错过执行作业重触发
  • 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例
  • 自诊断并修复分布式不稳定造成的问题
  • 支持并行调度
  • 支持作业生命周期操作
  • 丰富的作业类型
  • Spring 整合以及命名空间提供
  • 运维平台

2.2 springboot工程,引入依赖

<dependency>
    <groupId>com.github.yinjihuan</groupId>
    <artifactId>elastic-job-spring-boot-starter</artifactId>
    <version>1.0.2</version>
</dependency>
  • 因为这个当当网提供的jar包不在国外的maven仓库内,所以要使用GitHub 开源代码库
<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

在这里插入图片描述

2.3 配置文件

  • 需要 zookeeper 支持
# zk注册中心
elastic.job.zk.serverLists=127.0.0.1:2181
elastic.job.zk.namespace=job_elastic

server.port=8082

2.4 开启E-Job

  • @EnableElasticJob

在这里插入图片描述

2.5 创建ElasticService

package com.example.elasticjob.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class ElasticService {

    public void process(String sql) {
        log.info("当前执行sql:{}", sql);
    }

}

2.6 创建定时任务监听

package com.example.elasticjob.handle;

import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MessageElasticJobListener implements ElasticJobListener {
    public void beforeJobExecuted(ShardingContexts shardingContexts) {
        log.info("{}任务执行前",shardingContexts.getJobName());
    }

    public void afterJobExecuted(ShardingContexts shardingContexts) {
        log.info("{}任务执行后",shardingContexts.getJobName());
    }
}

2.7 创建定时任务异常处理类

package com.example.elasticjob.handle;

import com.dangdang.ddframe.job.executor.handler.JobExceptionHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CustomJobExceptionHandler implements JobExceptionHandler {
    public void handleException(String s, Throwable throwable) {
        log.info("{}发生异常了,给领导发邮件,{}", s, throwable.getMessage());
    }
}

2.8 创建定时任务

package com.example.elasticjob.job;

import com.cxytiandi.elasticjob.annotation.ElasticJobConf;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.example.elasticjob.service.ElasticService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

@Slf4j
@ElasticJobConf(name = "ElasticSimpleJob", cron = "0/5 * * * * ?",//配置触发时间
        //分片序列号和参数用等号分隔,多个键值对用逗号分隔;分片序列号从0开始,不可大于或等于作业分片总数
        shardingItemParameters = "0=nanjing,1=shanghai",
        shardingTotalCount = 2,//作业分片总数
        listener = "com.example.elasticjob.handle.MessageElasticJobListener",//任务开始和结束时,自定义的处理功能
        jobExceptionHandler = "com.example.elasticjob.handle.CustomJobExceptionHandler")//任务异常时,自定义的处理
public class ElasticSimpleJob implements SimpleJob {
    @Autowired
    private ElasticService elasticService;

    public void execute(ShardingContext shardingContext) {
        log.info("当前执行分片:{}", shardingContext.getShardingParameter());
        String sql = shardingContext.getShardingParameter();
        elasticService.process(sql);
    }
}

2.9 启动zookeeper,再使用8081端口启动服务

  • 当只有一个服务时间,会同时执行2个分片的sql

在这里插入图片描述

2.10 再使用8082端口启动服务

  • ElasticJobApplication类和ElasticJobApplication2类代码一样,只是为了同时启动2个服务,修改配置文件端口号,启动ElasticJobApplication2,可以看出只执行nanjing分片的sql

在这里插入图片描述

  • 再次查看ElasticJobApplication的打印,当有2个服务时,只会执行shanghai分片的sql

在这里插入图片描述

3. X-Job分布式调度

  • XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。与 E-Job 走无中心化方式不同,XXL-JOB 是中心集权方式。

3.1 使用场景

  • 当项目中定时任务非常多的时候,建议使用X-Job;
  • 由job配置中心通过quartz控制客户端job触发时机,然后通过netty rpc调用执行客户端的具体实现。使用中心化的方式可以极大地减少job的管理成本,还可以配置集群。

在这里插入图片描述

3.2 项目下载

在这里插入图片描述

3.3 初始化数据库

  • 在mysql中执行下面的sql脚本,Mysql版本要在5.7之上

在这里插入图片描述
在这里插入图片描述

3.4 编译源码

  • 执行mvn clean compile即可

在这里插入图片描述

3.5 配置调度中心(xxl-job-admin)

  • 修改配置文件,数据库地址,用户名,密码

在这里插入图片描述

3.6 启动调度中心

在这里插入图片描述

  • 调度中心如果要做集群部署时,由以下要求和建议:
    1、DB配置保持一致;
    2、集群机器时钟保持一致(单机集群忽视);
    3、建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。

3.7 登陆调度中心控制台

  • http://localhost:8080/xxl-job-admin,默认"admin/123456"。

在这里插入图片描述

3.8 配置执行器项目

  • 执行器就是业务系统,来接收“调度中心”的调度执行业务代码。
  • 在xxl-job-executor-samples中,作者为我们提供很多工作中常用的框架案例,大家可以把自己工作中的项目按照作者提供的例子进行改造,来使用xxl-job(要保证pom文件中引入了 “xxl-job-core” 的依赖)。如果是新项目也可以直接在作者的例子中进行开发。
  • 这里就直接使用作者提供的springboot版本执行器写一个定时任务进行测试。

在这里插入图片描述

  • 因为是本机测试,这里都是用的默认,什么都没改

在这里插入图片描述

3.9 创建测试类

  • SampleXxlJob类中,作者提供5中示例,还写了一些注意事项。

在这里插入图片描述

  • 创建一个测试类MyJob

在这里插入图片描述

3.10 启动执行器项目,添加任务

在这里插入图片描述
在这里插入图片描述

3.11 启动任务

在这里插入图片描述

  • 每隔1s执行一次

在这里插入图片描述

3.12 查看日志

在这里插入图片描述
在这里插入图片描述

3.13 线上操作

  • 可以随时停止或启动定时任务

在这里插入图片描述

  • 可以修改cron表达式

在这里插入图片描述

  • 使用glue(java),可以在线添加定时任务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值