柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

    • ruoyi-vue-plus-基础功能
    • ruoyi-vue-plus-权限控制
    • ruoyi-vue-plus-表格操作
    • ruoyi-vue-plus-缓存功能
    • ruoyi-vue-plus-日志功能
    • ruoyi-vue-plus-线程相关
    • ruoyi-vue-plus-OSS功能
    • ruoyi-vue-plus-代码生成功能
    • ruoyi-vue-plus-多数据源
    • ruoyi-vue-plus-任务调度
      • SpringBoot 任务调度
      • XXL-JOB 任务调度
        • 快速应用
        • 配置
        • ruoyi-admin模块 配置
        • xxl-job模块 配置
        • 前端配置
        • 路由执行策略
        • 邮箱警告
        • 高级应用
        • 命令行任务
        • **定时备份数据库
        • 生命周期任务
      • PowerJob 任务调度
    • ruoyi-vue-plus-监控功能
    • ruoyi-vue-plus-国际化
    • ruoyi-vue-plus-XSS功能
    • ruoyi-vue-plus-防重幂&限流 功能
    • ruoyi-vue-plus-推送功能
    • ruoyi-vue-plus-序列化功能
    • ruoyi-vue-plus-数据加密
    • ruoyi-vue-plus-单元测试
    • ruoyi-vue-plus-前端插件
    • ruoyi-vue-plus-前端工具篇
    • ruoyi-vue-plus-部署篇
    • ruoyi-vue-plus-前端篇
    • ruoyi-vue-plus-后端工具篇
    • ruoyi-vue-plus-框架篇
    • ruoyi-vue-plus-问题解决
  • 后端
  • Ruoyi-Vue-Plus
柏竹
2024-01-27
目录

ruoyi-vue-plus-任务调度

# SpringBoot 任务调度

官方文档 : https://spring.io (opens new window)

快速应用

  1. 启动类添加 @EnableScheduling注解 (启用任务调度)
  2. 新建一个类添加 @Component注解 (加载进Bean容器)
  3. 在新建类中的方法添加 @Scheduled注解 (定时任务)
  4. 运行即可实现

@Scheduled注解配置项

配置项 类型 描述
cron String 使用cron表达式定义任务执行周期
zone String 设定区域时间
fixedDelay long / String 指定周期时间间隔 , 上一个完成后后到下一个开始的间隔 (毫秒) ; String类型支持SpEL语法
initialDelay long / String SpringBoot运行后 , 首次任务执行延迟时间 (毫秒) ; String类型支持SpEL语法
fixedRate long / String 指定开始时间间隔 , 上一个开始后到下一个开始的间隔 (毫秒) ; String类型支持SpEL语法

提示

  • 点击了解 (opens new window) SpEL语法语法
  • 点击了解 (opens new window) cron表达式

# XXL-JOB 任务调度

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

官网 : https://www.xuxueli.com (opens new window)

XXL_Job在Ruoyi-vue-plus 5.x版本 废弃 , 仅应用4.x版本 . 5.x版本 点击跳转

# 快速应用

大致流程

  1. git拉去代码
  2. 加载库db库数据
  3. 配置 数据源、访问路径和端口
  4. 启动服务
  5. 访问 http://localhost:8080/xxl-job-admin (opens new window)
  6. 配置任务指定对应任务 (对应 @XxlJob注解的 值)
  7. 运行测试即可

配置


 
 






















 
 
 
 





































### 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/paper-system?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=xxx@qq.com
spring.mail.from=xxx@qq.com
spring.mail.password=xxx
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

# 配置

# ruoyi-admin模块 配置

application-{环境}.yml配置文件 (一般情况下不要动以下配置)

--- # xxl-job 配置
xxl.job:
  # 执行器开关
  enabled: true
  # 调度中心地址:如调度中心集群部署存在多个地址则用逗号分隔。
  admin-addresses: http://localhost:9100/xxl-job-admin
  # 执行器通讯TOKEN:非空时启用
  access-token: xxl-job
  executor:
    # 执行器AppName:执行器心跳注册分组依据;为空则关闭自动注册
    appname: xxl-job-executor
    # 28080 端口 随着主应用端口飘逸 避免集群冲突
    port: 2${server.port}
    # 执行器注册:默认IP:PORT
    address:
    # 执行器IP:默认自动获取IP
    ip:
    # 执行器运行日志文件存储磁盘路径
    logpath: ./logs/xxl-job
    # 执行器日志文件保存天数:大于3生效
    logretentiondays: 30

# xxl-job模块 配置

配置项在 ruoyi-xxl-job-admin模块中

主要关注 : 登录账号密码、数据库基础配置、邮箱通知配置

application-{环境}.yml配置文件 (一般情况下不要动以下配置)









 
 






 
 
 





























--- # 监控配置
spring.boot.admin.client:
  # 增加客户端开关
  enabled: true
  # 设置 Spring Boot Admin Server 地址
  url: http://localhost:9090/admin
  instance:
    service-host-type: IP
  username: ruoyi
  password: 123456

--- # 数据库配置
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ruoyi-vue?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    username: root
    password: root
    hikari:
      auto-commit: true
      connection-test-query: SELECT 1
      connection-timeout: 10000
      idle-timeout: 30000
      max-lifetime: 900000
      maximum-pool-size: 30
      minimum-idle: 10
      pool-name: HikariCP
      validation-timeout: 1000

--- # 邮件配置
spring:
  mail:
    from: bozhu12@foxmail.com
    host: smtp.foxmail.com
    username: bozhu12@foxmail.com
    password: apppwpcbxfmyhiaf
    port: 25
    properties:
      mail:
        smtp:
          auth: true
          socketFactory:
            class: javax.net.ssl.SSLSocketFactory
          starttls:
            enable: true
            required: true

# 前端配置

前端跳转配置涉及到指定url访问

配置 .env.development / .env.production 即可

# xxl-job 控制台地址
VUE_APP_XXL_JOB_ADMIN = 'http://localhost:9100/xxl-job-admin'

提示

要对应开放的url才能进行访问

# 路由执行策略

在多个执行器的情况下可以可采取以下策略

路由策略 说明
第一个 顺序中的第一个(非故障)
最后一个 顺序中的最后一个(非故障)
轮询 依次顺序执行
随机 随机分配执行
一致性HASH 根据执行器哈希值执行
最不经常使用 多个执行器中 , 判断使用次数最少一个
最近最久未使用 多个执行器中 , 判断最近最久一个
故障转移 过程中故障错误移至使用其他执行器
忙碌转移 过程中执行中移至使用其他执行器
分片广播 一个任务多个执行器分片执行 (控制器访问由代码逻辑控制)

其他策略字面意思就不过多讲解 , 主要还得看 分片广播

分片广播

@XxlJob("shardingJobHandler")
public void shardingJobHandler() throws Exception {

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

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

    for (int i = 0; i < 10000; i++) {
        if (i % shardTotal == shardIndex) {
            XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
        }
    }

}

# 邮箱警告

大致流程

  1. 启用邮箱服务 获取授权密码
  2. 配置邮箱信息 , 以及任务警告通知邮箱
  3. 启用任务测试..

邮箱配置

ruoyi-xxl-job-admin模块中 配置文件

# 邮件配置
spring:
  mail:
    from: bozhu12@foxmail.com
    host: smtp.qq.com
    username: bozhu12@foxmail.com
    # 自行去邮箱获取授权密码
    password: xxxxxxxxxx
    port: 25
    properties:
      mail:
        smtp:
          auth: true
          socketFactory:
            class: javax.net.ssl.SSLSocketFactory
          starttls:
            enable: true
            required: true

提示

foxmail邮箱的smtp协议是采用QQ提供的服务

在配置时可通过在任务中添加指定邮箱进行警告通知 , 多个邮箱可以采用 , 进行分割

# 高级应用

# 命令行任务

执行当前主机的命令

点击展开
@XxlJob("commandJobHandler")
public void commandJobHandler() throws Exception {
    String command = XxlJobHelper.getJobParam();
    int exitValue = -1;

    BufferedReader bufferedReader = null;
    try {
        // command process
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command(command);
        processBuilder.redirectErrorStream(true);

        Process process = processBuilder.start();
        //Process process = Runtime.getRuntime().exec(command);

        BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
        bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));

        // command log
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            XxlJobHelper.log(line);
        }

        // command exit
        process.waitFor();
        exitValue = process.exitValue();
    } catch (Exception e) {
        XxlJobHelper.log(e);
    } finally {
        if (bufferedReader != null) {
            bufferedReader.close();
        }
    }

    if (exitValue == 0) {
        // default success
    } else {
        XxlJobHelper.handleFail("command exit value(" + exitValue + ") is failed");
    }

}

# **定时备份数据库

通过命令执行备份脚本文件

  1. 编辑好备份脚本文件
  2. 定时执行备份脚本文件

http请求任务

点击展开
@XxlJob("httpJobHandler")
public void httpJobHandler() throws Exception {

    // param parse
    String param = XxlJobHelper.getJobParam();
    if (param == null || param.trim().length() == 0) {
        XxlJobHelper.log("param[" + param + "] invalid.");

        XxlJobHelper.handleFail();
        return;
    }

    // 解析参数结构
    String[] httpParams = param.split("\n");
    String url = null;
    String method = null;
    String data = null;
    for (String httpParam : httpParams) {
        if (httpParam.startsWith("url:")) {
            url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
        }
        if (httpParam.startsWith("method:")) {
            method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
        }
        if (httpParam.startsWith("data:")) {
            data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
        }
    }


    // 校验有效参数
    if (url == null || url.trim().length() == 0) {
        XxlJobHelper.log("url[" + url + "] invalid.");

        XxlJobHelper.handleFail();
        return;
    }
    if (method == null || !Arrays.asList("GET", "POST").contains(method)) {
        XxlJobHelper.log("method[" + method + "] invalid.");

        XxlJobHelper.handleFail();
        return;
    }
    boolean isPostMethod = method.equals("POST");

    // 发送请求
    HttpURLConnection connection = null;
    BufferedReader bufferedReader = null;
    try {
        URL realUrl = new URL(url);
        connection = (HttpURLConnection) realUrl.openConnection();

        // connection setting
        connection.setRequestMethod(method);
        connection.setDoOutput(isPostMethod);
        connection.setDoInput(true);
        connection.setUseCaches(false);
        connection.setReadTimeout(5 * 1000);
        connection.setConnectTimeout(3 * 1000);
        connection.setRequestProperty("connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");

        // do connection
        connection.connect();

        // data
        if (isPostMethod && data != null && data.trim().length() > 0) {
            DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
            dataOutputStream.write(data.getBytes("UTF-8"));
            dataOutputStream.flush();
            dataOutputStream.close();
        }

        // valid StatusCode
        int statusCode = connection.getResponseCode();
        if (statusCode != 200) {
            throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
        }

        // result
        bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        StringBuilder result = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            result.append(line);
        }
        String responseMsg = result.toString();

        XxlJobHelper.log(responseMsg);

        return;
    } catch (Exception e) {
        XxlJobHelper.log(e);

        XxlJobHelper.handleFail();
        return;
    } finally {
        try {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
            if (connection != null) {
                connection.disconnect();
            }
        } catch (Exception e2) {
            XxlJobHelper.log(e2);
        }
    }

}

# 生命周期任务

任务执行的声明周期分 : 任务初始 , 任务销毁 两种

点击展开
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
public void demoJobHandler2() throws Exception {
    XxlJobHelper.log("XXL-JOB, Hello World.");
}

public void init() {
    log.info("init");
}

public void destroy() {
    log.info("destory");
}

# PowerJob 任务调度

官网 : http://www.powerjob.tech (opens new window)

文档 : https://www.yuque.com (opens new window)

ruoyi-vue-plus应用文档 : https://plus-doc.dromara.org (opens new window)

ruoyi-vue-plue 5.x 版本采用 PowerJob任务调度

后续补充...

个人感觉官方文档已经写的不错了

#ruoyi-vue-plus#任务调度

← ruoyi-vue-plus-多数据源 ruoyi-vue-plus-监控功能→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式