最新若依SpringCloud分布式整合xxl-job2.4.0实战案例


一、xxl-job部分

1、xxl-job下载地址

官网地址:https://www.xuxueli.com/index.html
代码地址:https://github.com/xuxueli/xxl-job/

2、执行 tables_xxl_job.sql 文件

在这里插入图片描述

3、修改 xxl-job-admin 中 application.properties数据库地址

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_pwd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

建议serverTimezone=UTC

4、启动xxl-job-admin

访问地址:http://127.0.0.1:8080/xxl-job-admin
在这里插入图片描述账号:admin
密码:123456

二、XxlJobExecutorApplication部分

1.创建测试demo

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

@Component
public class SampleXxlJob {
    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
    /**
     * 1、简单任务示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");
        System.out.println("helloWord");
        for (int i = 0; i < 5; i++) {
            XxlJobHelper.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        // default success
    }


    /**
     * 2、分片广播任务
     */
    @XxlJob("shardingJobHandler")
    public void shardingJobHandler() throws Exception {

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

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

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

    }


    /**
     * 3、命令行任务
     */
    @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");
        }

    }


    /**
     * 4、跨平台Http任务
     *  参数示例:
     *      "url: http://www.baidu.com\n" +
     *      "method: get\n" +
     *      "data: content\n";
     */
    @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();
            }
        }

        // param valid
        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");

        // request
        HttpURLConnection connection = null;
        BufferedReader bufferedReader = null;
        try {
            // connection
            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);
            }
        }
    }

    /**
     * 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
     */
    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public void demoJobHandler2() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");
    }
    public void init(){
        logger.info("init");
    }
    public void destroy(){
        logger.info("destroy");
    }
}

2.检查并配置调度中心

检查XxlJobExecutorApplication服务启动是否成功,是否注册进xxl-job-admin
在这里插入图片描述
如果没有需要手动创建
在这里插入图片描述
application.properties文件中xxl.job.executor.appname=xxl-job-executor-sample 对应AppName(必须保持一致)不然找不到服务

### 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=
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

创建定时任务设置cron,JobHandler名必须@XxlJob(“demoJobHandler”)保持一致
在这里插入图片描述
在这里插入图片描述
配置完成后的结果
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
以上是 xxl-job内部调用

三、SpringCloud整合xxl-job实现跨服务调用

1.创建SpringCloud配置yml文件

xxl:
  job:
    admin:
      addresses: http://127.0.0.1:9090/xxl-job-admin 
    executor:
      address:
      appname: guoziwei-modules-job
      ip:
      port: 9999
      logpath: /data/applogs/xxl-job/jobhandler
      logretentiondays: 15
    accessToken: default_token

pom文件添加依赖

<!-- xxl-job-core -->
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>2.4.0</version>
        </dependency>

重点1:addresses配置xxl-job-admin的服务地址
重点2:appname配置本服务的appname以便在执行器管理中新增服务
重点3:配置完成后启动服务需要在xxl-job-admin执行器管理中新增 选择 自动注册即可 输入的AppName必须与yml文件配置的appname一样
在这里插入图片描述
最后新建一个测试类重复XxlJobExecutorApplication部分即可


### XXL-JOB 2.4 PostgreSQL Compatibility Configuration and Setup Guide For making XXL-JOB version 2.4 compatible with PostgreSQL, several steps need to be followed carefully as the official support is primarily for MySQL. The process involves obtaining source code modifications specific to PostgreSQL connectivity settings. The first step towards configuring XXL-JOB 2.4 for PostgreSQL includes acquiring or modifying the project's source code that supports this database system[^1]. This ensures all necessary changes are included within the application logic to interact properly with PostgreSQL instead of MySQL. Once the appropriate source code has been obtained, attention turns toward setting up the data source URL specifically designed for connecting to a PostgreSQL instance. An example configuration line would look like `spring.datasource.url=jdbc:postgresql://<host>:<port>/<database>` where placeholders should be replaced by actual values corresponding to one’s own environment setup such as IP address (or hostname), port number typically being 5432 unless changed otherwise during installation, and name of the target database intended for use with XXL-JOB[^2]. After ensuring both software-level adjustments through coding updates along with correct connection parameters provided via Spring Boot properties file or equivalent means depending on deployment strategy chosen; executing relevant SQL scripts becomes crucial next action item listed under preparatory tasks before running applications against new storage backend successfully configured earlier mentioned above[^3]. ```sql -- Example script execution command using psql client tool psql -U postgres -d xxl_job_db -f path/to/your/sql_script.sql ``` To verify everything works correctly after these configurations have taken place: - Start XXL-JOB scheduler service. - Monitor logs closely watching out especially any errors related directly either JDBC driver issues when establishing connections between Java runtime environment used here alongside Postgres server side component involved now post-migration efforts completed recently according previous instructions outlined previously throughout entire document so far presented hereinbefore. --related questions-- 1. What potential challenges might arise while adapting XXL-JOB from MySQL to PostgreSQL? 2. How can one troubleshoot common problems encountered during migration processes involving changing databases in distributed systems similar to what was described concerning XXL-JOB adaptation work done here today? 3. Are there alternative methods besides direct modification of source codes available for achieving cross-database compatibility across different versions including but not limited to those discussed already regarding XXL-JOB framework itself?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值