xxl-job分布式任务调度器的学习

news2024/11/27 11:53:15

先看一下原生的任务调度器

package com.xxl.job.executor.service.jobhandler;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class SpringBootScheduled {

    @Scheduled(cron = "*/5 * * * * *")
    public void test(){
        System.out.println("hello Scheduled");
    }
}

定时任务调度器在什么场景下使用呢?

房贷车贷的还款,花呗借呗白条的还款等等这种参加定时活动的场景。

原生的任务调度器有什么弊端呢?

1.在分布式环境下,每个应用都配一个任务调度器的话那么执行多次;

2.如果任务执行失败了,不能重试;执行异常了,不能报警;

3.重新配置了任务的话,必须要重启应用 等等。

所以需要选择一种机制进行定时调度,那就选择xxl-job,是中国人开发,完整的中文文档,低门槛,易于管理。

分布式任务调度平台XXL-JOB

0a6d9712cea44a3bab234c0bed3d9995.png

 这里选择GITEE下载,下载到本地的代码中有sql,doc,源码等等,

将sql执行到本地数据库

1e28a745e79f4510bc1e40a9f02eb4c4.png

其中xxl-job-admin属于调度中心,给的sample中的3个例子属于调度器

 

1.调度中心的配置

 Idea导入项目,配置中心要配好数据库访问地址和token(token为空也可以)

### web
server.port=8080
server.servlet.context-path=/xxl-job-admin

### actuator
management.server.servlet.context-path=/actuator
management.health.mail.enabled=false

### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/

### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########

### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
#mybatis.type-aliases-package=com.xxl.job.admin.core.model

### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

### datasource-pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=HikariCP
spring.datasource.hikari.max-lifetime=900000
spring.datasource.hikari.connection-timeout=10000
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.validation-timeout=1000

### xxl-job, email
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=962654683@qq.com
spring.mail.from=962654683@qq.com
spring.mail.password=5tgb^YHNn
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory

### xxl-job, access token
xxl.job.accessToken=default_token

### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")
xxl.job.i18n=zh_CN

## xxl-job, triggerpool max size
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100

### xxl-job, log retention days
xxl.job.logretentiondays=30

运行xxl-job-admin(运行项目之前执行sql,而且一定要mvn-->clean一下

bfec1abed57047fcae4596c09dac6e49.png

默认的用户名密码是admin/123456

d99d85b173124bfdaacb22368633ccea.png

 

 

2.调度器的配置:

1,引入core依赖包

2.配置application.properties

# web port
server.port=8081
# no web
#spring.main.web-environment=false

# log config
logging.config=classpath:logback.xml


### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin 

### xxl-job, access token
xxl.job.accessToken=default_token

### xxl-job executor appname
xxl.job.executor.appname=xxl-job-executor-sample
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=127.0.0.1
xxl.job.executor.port=9999
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin 要写配置中心的地址

xxl.job.accessToken=default_token要和调度中心中的token对应

xxl.job.executor.ip=127.0.0.1 配置注册器所在的地址
xxl.job.executor.port=9999   注册中心向注册器发送信息的端口

3.配置config类

package com.xxl.job.executor.core.config;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */
@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appname;

    @Value("${xxl.job.executor.address}")
    private String address;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }

    /**
     * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
     *
     *      1、引入依赖:
     *          <dependency>
     *             <groupId>org.springframework.cloud</groupId>
     *             <artifactId>spring-cloud-commons</artifactId>
     *             <version>${version}</version>
     *         </dependency>
     *
     *      2、配置文件,或者容器启动变量
     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
     *
     *      3、获取IP
     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
     */


}

4. Component类,

@Component
public class SampleXxlJob {
    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);


    /**
     * 1、简单任务示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public ReturnT<String> demoJobHandler(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");

        System.out.println("XXL-JOB, Hello World. a");
        for (int i = 0; i < 5; i++) {
            XxlJobLogger.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        return ReturnT.SUCCESS;
    }

}

 

两个项目(任务中心和执行器)启动,之后访问http://localhost:8080/xxl-job-admin

1.Bean的运行模式

点击任务列表,新增,选择Bean的运行模式,任务描述对应:@XxlJob("demoJobHandler")中的demoJobHandler,配置好Cron

10214b86aeb44a7993355d459a756833.png

 de4038a5d7114e3792981e0b186c0fb2.png

 之后就可以执行了。添加之后,操作中的启动即可。

7bdd662ea4944b9b8fec239d9c98c725.png

 

4ad36779edda44f58daab23d85e7938f.png

2.GLUE(Java)模式

上面说的是Bean模式,那么还有一种很重要的模式:GLUE(Java)模式,

6279974c4bb84be7807b7300cce08433.png

 选择这个模式的时候,JobHandler为灰色不可编辑

8c19e24f50f5463d985607fff949f84a.png

但是 添加之后有这个Glue IDE

点击GLue IDE可以编辑代码,这里写代码的时候别忘了引入包,AbcService是在执行器里的代码

package com.xxl.job.service.handler;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;

import com.xxl.job.executor.mvc.service.AbcService;
import org.springframework.beans.factory.annotation.Autowired;

public class DemoGlueJobHandler extends IJobHandler {

     @Autowired
      private AbcService abcService ;
  
	@Override
	public ReturnT<String> execute(String param) throws Exception {
      
      
      abcService.methodA(param);
		XxlJobLogger.log("XXL-JOB, Hello World.");
		return ReturnT.SUCCESS;
	}

}

这里保存的时候还可以进行版本的控制,非常方便

点击运行,

c874279e2ed24deaa913489b31e67750.png

 这种glue的方式适合在线上运行但是还想去新加定时任务的情况下使用。

负载均衡

负载均衡:在任务管理中,新增任务的时候,有一个路由策略,可以进行集群的负载均衡。

a3c4fd5722034bcc9d520b07974e18d5.png

 

356d4f9c77d64e78b073f082b227732c.png

 将应用启动两个,修改对应的服务端口和调度中心调用执行器的接口,之后启动两个服务。 f8c24fb982654d819805f397783ea30d.png

 在执行器管理中,可以看到有两个执行器了

3d960151f98a41d09494072b10fb0e70.png

 

点击查看:

ff7068ec47a74347b41bd8c4064af55d.png

 如果我们选择“轮询”的方式,那么我们会发现两个服务会轮流执行。

分片广播

还有一种路由策略:分片广播的方式。

5429b1207d3a42808dce7793c8645d70.png

 这种方式很重要,应用场景:当我们执行一个耗时的操作的时候,可以让多个执行器一起执行,比如说只有一个执行器执行的话用20s,那么我们用分片广播的方式就可以10s完成执行。

  /**
     * 2、分片广播任务
     */
    @XxlJob("shardingJobHandler")
    public ReturnT<String> shardingJobHandler(String param) throws Exception {

        // 分片参数
        int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
        int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();

        XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);

        long l1 = System.currentTimeMillis();
        System.out.println(l1);
        List<UserMobilePlan> userMobilePlans ;
        if(shardTotal==1){
            userMobilePlans =userMobilePlanMapper.selectAllUser();
        }else{
            userMobilePlans = userMobilePlanMapper
                    .selectAllUserMobilePlans(shardIndex, shardTotal);
        }
        userMobilePlans.stream().map(userMobilePlan -> {
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return userMobilePlan;
        }).collect(Collectors.toList());
        long l2 = System.currentTimeMillis();
        System.out.println("花费时间:" + (l2-l1)+"ms");

        // 业务逻辑
//        for (int i = 0; i < shardTotal; i++) {
//            if (i == shardIndex) {
//                XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
//            } else {
//                XxlJobLogger.log("第 {} 片, 忽略", i);
//            }
//        }

        return ReturnT.SUCCESS;
    }

 

 ps:XXL-JOB的架构图        

01ab0e2fe7ae48bc8198feb9960ef2fc.png

官方的文档:分布式任务调度平台XXL-JOB

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/780251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.Docker网络和资源控制

文章目录 Docker操作二Docker网络实现原理端口映射查看日志 网络模式host模式container模式none模式bridge模式自定义网络 Docker资源控制CPU资源控制设置CPU使用率上限设置CPU资源占用比&#xff08;设置多个容器才有效&#xff09;设置容器绑定指定CPU 内存使用限制设置磁盘I…

RK3399移植u-boot

RK3399移植u-boot 0.前言一、移植1.交叉工具链安装2.获取bl31.elf3.移植u-boot1)下载&#xff1a;2)配置&#xff1a;修改串口波特率&#xff1a;修改emmc&#xff1a;配置FIT&#xff1a;配置boot delay&#xff1a;(可选) 3)编译&#xff1a;4)生成idbloader.img文件&#xf…

使用 Docker 快速上手中文版 LLaMA2 开源大模型

本篇文章&#xff0c;我们聊聊如何使用 Docker 容器快速上手朋友团队出品的中文版 LLaMA2 开源大模型&#xff0c;国内第一个真正开源&#xff0c;可以运行、下载、私有部署&#xff0c;并且支持商业使用。 写在前面 感慨于昨天 Meta LLaMA2 模型开放下载之后&#xff0c;Git…

实验五 分支限界法

实验五 分支限界法 01背包问题的分治限界法的实现 剪枝函数 限界函数 1.实验目的 1、理解分支限界法的剪枝搜索策略&#xff0c;掌握分支限界法的算法框架 2、设计并实现问题&#xff0c;掌握分支限界算法。 2.实验环境 java 3.问题描述 给定n种物品和一背包。物品i的重…

JMeter基础入门教程之CSV数据文件设置CSV Data Set Config

最近在做压力测试&#xff0c;登录功能用到了配置元件&#xff1a;CSV 数据文件设置&#xff0c;可以将登录用户名和密码放在一个csv文件中&#xff0c;然后通过CSV数据文件设置元件读取出来&#xff0c;用来做压测。 一、CSV文件 CSV文件小知识分享&#xff1a;是指"逗号…

Linux内核--内存管理

MMU的产生背景 在计算机出现的早期&#xff0c;其内存资源十分有限&#xff0c;一般只有几十几百KB&#xff0c;当时的程序规模也小&#xff0c;对于当时的程序而言&#xff0c;KB级的内存资源尚足够使用。但随着计算机技术的发展&#xff0c;应用程序的规模不断膨胀&#xff…

k8s部署wordpress+mysql博客平台

k8s部署wordpressmysql博客平台 1、yaml文件准备1.1 wordpress-db.yaml1.2 wordpress.yaml 2、部署安装2.1 先创建wordpress命名空间2.2 部署wordpress-db2.3部署wordpress 3、访问测试 1、yaml文件准备 1.1 wordpress-db.yaml apiVersion: apps/v1kind: Deploymentmetadata:…

【flink】ColumnarRowData

列式存储 在调试flink读取parquet文件时&#xff0c;读出来的数据是ColumnarRowData&#xff0c;由于parquet是列式存储的文件格式&#xff0c;所以需要用一种列式存储的表示方式&#xff0c;ColumnarRowData就是用来表示列式存储的一行数据&#xff0c;它包含多个数组的数据结…

Matlab求解基于RRT算法的自定义垛型的路径避障

目录 背景 1 RRT搜索算法 2 基于Matlab的RRT搜索算法 3 基于Matlab的自定义垛型绘制 4 基于RRT算法的自定义垛型的路径避障 背景 在码垛机械臂路径规划过程中&#xff0c;需要根据现有箱子的码垛状态&#xff0c;给出下一个箱子的最佳码放无碰撞路径。RRT 快速搜索随机…

vue2项目 自定义详情组件

vue2项目 自定义详情组件 效果组件代码组件引入以及传参格式寄语 效果 组件代码 DetailFormRow.vue已经封装好&#xff0c;根据数据格式直接引用即可。 <template><div class"detail-form"><el-row class"detail-form-row" style"ma…

基本函数、常见曲线图像

基本函数图像是指一些常见的数学函数的图像&#xff0c;这些函数在数学和工程等领域中经常被使用。下面是一些常见的基本函数及其图像&#xff1a; 参考文献&#xff1a;同济版高等数学【第七版】上下册教材

几张表格搞定Mysql的SQL语句

一、数据库的登录与退出 登录Mysqlmysql -uroot -p123退出Mysqlexit 二、对数据库的操作 查询所有数据库show databases;创建数据库create database 数据库名字;删除数据库drop database 数据库名字;查询创建数据库的具体语句show create database 数据库名字;使用数据库use…

自学网络安全(黑客),遇到问题怎么解决

自学网络安全很容易学着学着就迷茫了&#xff0c;找到源头问题&#xff0c;解决它就可以了&#xff0c;所以首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题&#xff0c;看到后面有惊喜哦 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xf…

RocketMQ的系统设计

消息存储 下图为producer、broker、consumer的交互过程 1.消息存储整体架构 CommitLog&#xff1a;消息主体以及元数据的存储主体&#xff0c;存储Producer端写入的消息主体内容(即Producer端投递的消息都会先写入CommitLog中)&#xff0c;消息内容不是定长的。单个文件大小默…

代码随想录day8 | KMP 28.实现strStr() 459.重复的子字符串

文章目录 一、实现strStr()二、重复的子字符串 一、实现strStr() 先学学KMP算法&#xff0c;代码随想录 28.实现strStr() class Solution { public:void getNext(int* next, const string& s) {int j -1;next[0] j;for(int i 1; i < s.size(); i) { // 注意i从1开始…

win 安装虚拟机 再安装macos

0 视频教程 windows虚拟机一键安装苹果系统macos&#xff0c;轻松拥有xcode环境_哔哩哔哩_bilibili在windows环境下vmware虚拟机一键安装macos Catalina10.15.7苹果系统&#xff0c;帮助学习ios编程的朋友们实现xcode环境。文字教程&#xff1a;https://www.dhzy.fun/archives…

【Matlab】基于遗传算法优化 BP 神经网络的数据分类预测(Excel可直接替换数据)

【Matlab】基于遗传算法优化 BP 神经网络的数据分类预测&#xff08;Excel可直接替换数据&#xff09; 1.模型原理2.文件结构3.Excel数据4.分块代码4.1 arithXover.m4.2 delta.m4.3 ga.m4.4 gabpEval.m4.5 initializega.m4.6 maxGenTerm.m4.7 nonUnifMutation.m4.8 normGeomSel…

Qt ComboBox 下拉框设置多列

Qt ComboBox 下拉框设置多列 通过设置listview实现。 class MultiColumnComboBoxItemDelegate; class MultiColumnComboBoxListView;class MultiColumnComboBox : public QComboBox {Q_OBJECT public:explicit MultiColumnComboBox(QWidget *parent nullptr);~MultiColumnCo…

Linux -- 进阶 自动挂载服务 ( autofs ) 介绍及安装 主配置文件分析

背景引入 &#xff1a; 针对于 挂载 &#xff0c; 大家有没有思考过一个问题&#xff0c;如果我们需要挂载的文件或访问的远程数据甚至只是挂载一些设备&#xff0c;如果太多的话&#xff0c;数量很大的话&#xff0c;那 光每次挂载 敲的 mount 命令&#xff0c;都得敲很多遍…

Flask 文件上传,删除上传的文件

目录结构 app.py from flask import Flask, request, render_template, redirect, url_for import osapp Flask(__name__) BASE_DIR os.getcwd() UPLOAD_FOLDER os.path.join(BASE_DIR, testfile)app.route(/) def home():files os.listdir(UPLOAD_FOLDER)return render_t…