xxl-job学习及与Sharding-JDBC实现分片进行es同步

1. XXL-Job 的重点内容

XXL-Job 是一款分布式任务调度框架,核心解决是解决分布式环境下任务的统一调度、负载均衡和高可用问题,其重点内容包括:

  • 核心组件

    • 调度中心(Admin):集中管理任务配置、触发调度、监控执行状态,支持集群部署(基于数据库实现分布式锁保证一致性)。
    • 执行器(Executor):部署在业务服务中,接收调度中心指令并执行任务,支持集群部署(自动注册到调度中心)。
    • 任务(Job):业务逻辑载体,支持 BEAN 模式(类方法)和 GLUE 模式(动态脚本)。
  • 核心特性

    • 分布式调度:突破单机限制,任务可在多执行器间分发。
    • 分片执行:大任务按规则拆分(如 100 万条数据拆分为 10 个分片),并行处理。
    • 弹性扩容:执行器集群动态增减时,任务自动重新分配。
    • 失败重试:支持失败后自动重试(可配置次数和间隔)。
    • 监控报警:任务状态可视化,支持邮件、钉钉等报警方式。
    • 日志追踪:执行日志集中存储,支持在线查看。

2. XXL-Job 各类策略及含义

(1)路由策略(任务分配到哪个执行器)

决定任务请求发送到哪个执行器实例:

  • 第一个:固定选择第一个在线执行器。
  • 最后一个:固定选择最后一个在线执行器。
  • 轮询:按顺序依次分配给每个执行器(负载均衡常用)。
  • 随机:随机选择执行器(适合无状态任务)。
  • 一致性 HASH:相同参数的任务始终分配给同一执行器(适合有状态任务,如分片数据处理)。
  • 最不经常使用(LFU):优先分配给历史负载最低的执行器。
  • 最近最久未使用(LRU):优先分配给最近最少被使用的执行器。
  • 故障转移:优先选择健康的执行器(跳过故障实例)。
  • 分片广播:所有执行器都接收任务,但仅处理自己负责的分片(分片任务专用)。
(2)阻塞处理策略(任务触发时前一次未执行完)
  • 单机串行:等待前一次执行完成后再执行新任务(默认)。
  • 丢弃后续调度:若任务阻塞,直接丢弃新的调度请求。
  • 覆盖之前调度:用新任务覆盖正在执行的旧任务(适合实时性要求高的场景)。
(3)失败处理策略(任务执行失败后)
  • 失败告警:仅触发报警,不重试。
  • 失败重试:按配置的重试次数自动重试(重试间隔可配置)。
(4)触发策略(任务何时执行)
  • CRON 表达式:基于时间的灵活调度(如每天凌晨 2 点执行)。
  • 固定间隔:按固定时间间隔触发(如每隔 30 分钟)。
  • 固定延迟:上一次执行完成后延迟固定时间触发(如执行完延迟 10 分钟)。
  • 手动触发:通过控制台手动触发执行。

3. Java 引入 XXL-Job 的流程

(1)部署调度中心(Admin)
  1. 下载源码:从 XXL-Job 官网 获取最新版本。
  2. 初始化数据库:执行 doc/db/tables_xxl_job.sql 创建调度中心所需表。
  3. 配置调度中心:修改 application.properties 中的数据库连接和端口(默认 8080)。
  4. 启动调度中心:运行 XxlJobAdminApplication 主类。
(2)项目引入依赖
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.0</version> <!-- 需与调度中心版本一致 -->
</dependency>
(3)配置执行器
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class XxlJobConfig {

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses; // 调度中心地址

    @Value("${xxl.job.executor.appname}")
    private String appname; // 执行器名称(需与控制台配置一致)

    @Value("${xxl.job.executor.port:9999}")
    private int port; // 执行器端口

    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        XxlJobSpringExecutor executor = new XxlJobSpringExecutor();
        executor.setAdminAddresses(adminAddresses);
        executor.setAppname(appname);
        executor.setPort(port);
        // 可选:配置日志路径、访问令牌等
        return executor;
    }
}
(4)配置文件(application.properties)
# 调度中心地址(多个用逗号分隔)
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
# 执行器名称(唯一标识)
xxl.job.executor.appname=my-executor
# 执行器端口(默认 9999,多实例需不同)
xxl.job.executor.port=9999
(5)编写任务处理器
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;

@Component
public class MyJobHandler {

    // 任务标识:需与控制台配置的 JobHandler 一致
    @XxlJob("myShardingJob")
    public void execute() throws Exception {
        // 任务逻辑
        System.out.println("执行分片任务...");
    }
}
(6)控制台配置任务
  1. 登录调度中心(默认账号 admin/123456)。
  2. 新增执行器:配置执行器名称(与 appname 一致)。
  3. 新增任务:填写任务名称、执行器、JobHandler(与 @XxlJob 注解值一致)、路由策略、分片参数等。

4. XXL-Job 在 Sharding-JDBC 中的分片执行

Sharding-JDBC 负责数据分片存储(如按 id%10 分 10 张表),XXL-Job 按相同规则拆分任务,实现分布式并行处理。

(1)Sharding-JDBC 分表配置(以 10 张表为例)
spring:
  shardingsphere:
    datasource:
      names: ds_1
      ds_1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db?useSSL=false
        username: root
        password: 123456

    rules:
      sharding:
        tables:
          user:
            actual-data-nodes: ds_1.user_${0..9} # 10 张分表
            table-strategy:
              standard:
                sharding-column: id # 分片键
                sharding-algorithm-name: user_inline
        sharding-algorithms:
          user_inline:
            type: INLINE
            props:
              algorithm-expression: user_${id % 10} # 分表规则
(2)XXL-Job 分片任务实现
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserSyncJob {

    @Autowired
    private UserService userService;

    // 任务标识:与控制台配置一致
    @XxlJob("userSyncJob")
    public void syncUserToEs() {
        // 获取分片参数(控制台配置分片参数为 0-9)
        int shardIndex = XxlJobHelper.getShardIndex(); // 当前分片索引(0-9)
        int shardTotal = XxlJobHelper.getShardTotal(); // 总分片数(10)

        try {
            // 按分片同步数据(规则与 Sharding-JDBC 一致:id%10=shardIndex)
            long count = userService.syncByShard(shardIndex);
            XxlJobHelper.handleSuccess("分片" + shardIndex + "同步完成,处理" + count + "条");
        } catch (Exception e) {
            XxlJobHelper.handleFail("分片" + shardIndex + "失败:" + e.getMessage());
        }
    }
}
(3)Service 层实现分片查询
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private EsClient esClient;

    // 按分片同步数据
    public long syncByShard(int shardIndex) {
        // Sharding-JDBC 自动路由到 user_${shardIndex} 分表
        List<User> users = userMapper.selectByShard(shardIndex);
        
        if (!users.isEmpty()) {
            esClient.bulkInsert(users); // 批量写入 ES
        }
        return users.size();
    }
}
(4)Mapper 层查询
import org.apache.ibatis.annotations.Param;
import java.util.List;

public interface UserMapper {
    // 按分片查询(where 条件与分表规则一致)
    @Select("SELECT * FROM user WHERE id % 10 = #{shardIndex}")
    List<User> selectByShard(@Param("shardIndex") int shardIndex);
}
(5)控制台配置分片任务
  • 分片参数:0-9(总分片数 10)。
  • 路由策略:分片广播(确保所有执行器接收任务)。

5. XXL-Job 使用注意事项

  1. 分片策略一致性

    • XXL-Job 分片数必须与 Sharding-JDBC 分表数一致,否则会出现数据漏处理或重复处理。
    • 分片规则(如 id%10)必须完全相同,确保任务与数据分片对齐。
  2. 执行器集群部署

    • 执行器端口需唯一(避免冲突),建议通过 -Dxxl.job.executor.port=9999 动态指定。
    • 执行器名称(appname)必须一致,否则调度中心无法识别为同一集群。
  3. 任务幂等性

    • 任务可能因重试、网络波动等重复执行,需确保业务逻辑幂等(如基于 id 去重)。
  4. 资源控制

    • 单个任务避免处理过大数据量,建议分页批量处理(如每次 500 条)。
    • 配置合理的线程池参数(执行器默认核心线程数为 20),避免线程耗尽。
  5. 日志与监控

    • 生产环境关闭 SQL 日志(sql-show: false),避免性能损耗。
    • 配置任务超时时间(如 300 秒)和失败报警,及时发现异常。
  6. 版本兼容性

    • 执行器与调度中心版本必须一致,否则可能出现通信异常。
  7. 动态扩容

    • 新增执行器后,调度中心会自动发现,任务会重新负载均衡。
    • 分表扩展时,需同步调整 XXL-Job 分片参数(如从 10 改为 11)并迁移数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不见长安在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值