XXL-Job实战(千万级短信推送实战)

news2024/11/29 10:48:55

上回我们介绍了传统定时任务与分布式任务调度的差异以及它们的优缺点,本节我们使用Xxl-job来实现相关需求。

首先我们需要下载Xxl-job对应的服务端;下面是Xxl-job的github地址:

Releases · xuxueli/xxl-job (github.com)

版本我们选择V-2.3.0版本。
在这里插入图片描述
本地解压导入idea编译器中,并配置数据源:
在这里插入图片描述
在xxl-job-admin模块中application.properties中进行配置:
在这里插入图片描述
在配置文件中,我们除了可以配置数据源之外,还可以配置邮件告警信息,就是说当任务执行失败,给已发送邮件给对应的开发去排查相关问题。
在这里插入图片描述
为了安全考虑,我们还可以配置token:
在这里插入图片描述
配置完成后,我们还需要将xxl-job为我们提供的数据表导入数据库中,相关的sql文件在doc/db目录下:
在这里插入图片描述
执行以上sql文件到数据库中:
在这里插入图片描述
当以上步骤完成后,我们就可以启动xxl-job,访问端口可以查看我们的服务端了。
在这里插入图片描述
可以看到我们的服务端已经启动成功,下面我们来访问一下:

localhost:8080/xxl-job-admin;账号密码为:admin/123456
在这里插入图片描述
可以看到服务部署成功了。到此先暂停下,先梳理下xxx-job部署的步骤,有哪些点需要注意。

下面我们去开发我们对应的需求。

首先进入我们自己的项目中,导入xxl-job相关依赖:

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

添加配置文件,这里我是用的yml形式的配置文件,当然你们也可以使用application.properties配置文件,两者不冲突哦。

xxl:
  job:
    accessToken: # 这个要跟服务断我们配置的token一致
    admin:
      # 部署的服务端地址
      addresses: http://192.168.31.25:8080/xxl-job-admin
    executor:
      # address可以不写,可以在服务端配置执行器选择自动注册就好了
      # address: 192.168.31.25:8080
      appname: xdclass-user-xxl-job
      # ip: 192.168.31.25
      logpath: ./data/logs/xxl-job/executor
      logretentiondays: 30
      # 注册的端口,默认是9999
      port: 8893

下面我们需要开发一个配置文件来读取上面的配置:


/**
 * @Author: LiFly
 * @Date: 2024/6/19 15:50
 * @Description:
 */
@Configuration
@Slf4j
public class XxlJobConfig {

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

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

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

//    @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 xxlJobSpringExecutor(){
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddress);
        xxlJobSpringExecutor.setAppname(appName);
//        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogRetentionDays(logretentionDays);

        return xxlJobSpringExecutor;
    }
}

大致就长成这样,配置类开发好,我们就可以来编写个demo来测试下:


/**
 * @Author: LiFly
 * @Date: 2024/6/19 16:00
 * @Description:
 */
@Component
public class MyJobHandler {

    private final Logger log = LoggerFactory.getLogger(MyJobHandler.class);

    @Autowired
    private UserService userService;

    @XxlJob("userJobHandler")
    public ReturnT<String> execute(String param){
      JsonData jsonData =  userService.detail(1798667808547328001L);
      log.info("myJobHandler data={}",jsonData.getData().toString());
      return ReturnT.SUCCESS;
    }

      private void init(){
        log.info(" init success >>>>>>>>>>>>");
    }

    private void destroy(){
        log.info(" destory success >>>>>>>>>>>>>");
    }
}

上面的job就是说要查询id为1798667808547328001L的详细信息。开发好我们的demo后,我们就可以启动项目,登录xxl-job-admin来配置我们的任务调度器。
在这里插入图片描述
在执行器管理中,我们选择新增执行器。
在这里插入图片描述
AppName:与我们的配置文件一致:xdclass-user-xxl-job

名称就自己取一个就可以了,注册方式我们选择自动注册,也可以手动录入,看自己选择就可以了,选择保存,我们来到任务管理,选择添加任务。
在这里插入图片描述
执行器要与我们刚刚创建的执行器名称对应上哈。点击新增:
在这里插入图片描述
这里我们填写对应的任务描述,负责人;其他的默认就行,JobHandler名称就是我们在项目中开发的任务名称:userJobHandler;然后我们选择保存。下面就是见证奇迹的时刻了;回到任务管理,点击操作,我们选择执行一次,然后我们去调度日志中查看日志:
在这里插入图片描述
在这里插入图片描述我们可以看到执行成功,下面我们来到我们的项目看下刚才执行的日志:
在这里插入图片描述
可以看到,我们控制台也打印了相关日志,说明我们的demo执行成功了。到此我们的xxl-job服务端和客户端都已部署成功了,也测试成功了。

下面我们来开发我们的需求,在开发需求之前我们还需要了解下xxl-job中的分片任务,并以此来开发我们的需求。

分片任务:

  • 执行器集群部署,如果任务的路由策略选择【分片广播】,一次任务调度将会【广播触发】对应集群中所有执行器执行一次任务,同时系统自动传递分片参数,执行器可根据分片参数开发分片任务

  • 需要处理的海量数据,以执行器为划分,每个执行器分配一定的任务数,并行执行

  • XXL-Job支持动态扩容执行器集群,从而动态增加分片数量,到达更快处理任务

  • 分片的值是调度中心分配的


// 当前分片数,从0开始,即执行器的序号
int shardIndex = XxlJobHelper.getShardIndex();
//总分片数,执行器集群总机器数量
int shardTotal = XxlJobHelper.getShardTotal();

在这里插入图片描述
我们的需求是:构建一个分布式短信发送系统,应对双十一活动需向1000万用户快速推送营销短信的挑战,每条数据的业务处理逻辑为0.1s。对于普通任务来说,只有一个线程来处理 可能需要10万秒才能处理完,业务则严重受影响。

如果将1000万用户数据分发达10台机器,采用分片广播策略,只需要1万秒就可以了。

下面我们来模拟1000用户,分片处理,在项目中新开发一个job

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

        //获取当前执行器编号
        int shardIndex = XxlJobHelper.getShardIndex();
        //总的分片数,就是执行器的集群数量
        int shardTotal = XxlJobHelper.getShardTotal();
        log.info("分片总数shardTotal={},当前分片数shardIndex={}",shardTotal,shardIndex);

        List<Integer> allUserIds = getAllUserIds();

        allUserIds.forEach(obj->{
            if (obj % shardTotal == shardIndex){
                log.info("第{}片,命中分片开始处理用户id={}",shardIndex,obj);
            }
        });
    }

    private List<Integer> getAllUserIds() {

        List<Integer> ids = new ArrayList<>();

        for (int i = 0; i < 1000; i++) {
            ids.add(i);
        }
        return ids;

    }

下面我们模拟3台集群,同一个服务分别不同端口来启动,注册端口也需要不同,第一个服务端口为8991,注册端口为8891;第二个服务服务端口为8992,注册端口为8892;第三额服务端口为8993,注册端口为8893;分别启动服务;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们登录xxl-job-admin创建执行器,配置任务管理器,
在这里插入图片描述
在这里插入图片描述
点击操作中的执行一次,我们去看下控制台打印的信息:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过以上测试我们实现了分片处理1000条数据数据,3台处理器执行。从而可以更快地处理任务。

经过细致的部署与实践,我们不仅成功搭建了基于XXL-Job的分布式短信发送系统雏形,还深入探索了其分片任务的强大功能,为应对双十一等大规模营销活动的短信推送挑战提供了强有力的技术支撑。从XXL-Job服务端的快速部署、客户端项目的无缝集成,到分片策略的巧妙运用,每一步都展现了XXL-Job在处理高并发、大数据量任务上的灵活性与高效性。

通过模拟1000用户数据的分片处理,我们见证了任务在分布式环境下的加速执行过程。仅需简单的配置与代码调整,即可实现任务在多台服务器间的智能分配,显著提升了处理速度,将原本单一任务可能需要的漫长执行时间缩短至更合理的范畴。这一过程不仅验证了分片广播策略的有效性,也为后续扩展至1000万用户的真实场景奠定了坚实的基础。

总结而言,XXL-Job不仅是一款功能强大的分布式任务调度框架,更是一个促进系统架构优化、提升业务响应速度的有力工具。通过本次实践,我们深刻体会到了合理的任务分片与分布式部署对于应对大规模数据处理的重要性,为构建高性能、高可用的短信发送系统提供了宝贵的经验。未来,随着系统的不断优化与扩展,相信XXL-Job将继续发挥其核心作用,助力企业技术栈在复杂业务需求面前游刃有余,从容不迫。

更多内容,请关注一下公众号:
在这里插入图片描述

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

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

相关文章

【iOS】编译二进制文件说明

编译二进制文件说明 如何生成文件路径文件说明第一部分&#xff1a;.o文件第二部分&#xff1a;link第三部分&#xff1a;Segment第四部分&#xff1a;Symbol 如何生成 使用Xcode进行编译 &#xff0c;会生成二进制相关文件&#xff0c;可以更详细看产物的布局 项目Target -&…

Python统计实战:一题搞定多元线性回归、共线性、相对重要性分析

为了解决特定问题而进行的学习是提高效率的最佳途径。这种方法能够使我们专注于最相关的知识和技能&#xff0c;从而更快地掌握解决问题所需的能力。 &#xff08;以下练习题来源于《统计学—基于Python》。联系获取完整数据和Python源代码文件。&#xff09; 练习题 为了分析…

自动控制原理出射角计算

背景&#xff1a;突然发现自己出射角不会算 被减数是零点到极点的角度&#xff0c;减数是极点到极点的角度

十大经典排序算法——插入排序与希尔排序(超详解)

一、插入排序 1.基本思想 直接插入排序是一种简单的插入排序法&#xff0c;基本思想是&#xff1a;把待排序的记录按其数值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列。 2.直接插入排序 当插入第 e…

NSIS 入门教程 (二)

引言 在教程的第一部分中创建第一个安装程序后,我们还将需要删除其安装区段中已安装的文件。我们还将展示更多安装引导页面&#xff0c;让用户有机会选择安装的某些部分。 卸载 创建一个安装程序.可以干净的卸载,不仅是一种礼貌&#xff0c;对于程序的开发与发行方也有很…

【鸿蒙】 模拟器运⾏

【鸿蒙】HUAWEI DevEco Studio安装-CSDN博客 【鸿蒙】创建第⼀个鸿蒙项⽬-CSDN博客 点击 Tools 菜单下的 Device Manager 点击 Install &#xff0c;安装模拟器 下载模拟器相关的SDK&#xff0c;点击 Finish 选择安装⽬录&#xff0c;点击 New Emulator 选择设备类型&#…

大疆炸机后MOV修复方法(DJI Inspire 3)

dji大疆可以说是无人机中的华为&#xff0c;产品线之广性能之高让高傲的美国人侧面&#xff0c;质量和性价比才是王道。另外产品线的细分也是制胜法宝&#xff0c;无论是手持、农用机、特殊无人机还是影视级产品DJI都有涉及&#xff0c;给人的感觉就是在无人机细分方面它已经无…

LeetCode 算法:排序链表 c++

原题链接&#x1f517;&#xff1a;排序链表 难度&#xff1a;中等⭐️⭐️ 题目 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输…

Windows11系统自动获取电脑IPV6地址,并且开机自动发送到指定邮箱

废话&#xff1a;最近放假回家&#xff0c;在家里突然想玩游戏了&#xff0c;Steamdeck性能终归有限。部分游戏始终玩的不爽&#xff0c;想到之前了解到的SunshnieMoonlight串流的方案&#xff0c;远程调用家里的电脑打游戏&#xff0c;简直不要太爽。 一顿折腾之后配置好了所有…

C语言| 数组的顺序查找

顺序查找 查找数组a中第一次出现数字m的下标&#xff0c;并输出该下标&#xff1b; 如果没有则输出sorry。 1 定义变量 数组a&#xff0c;n表示数组的个数&#xff0c; m要查找的数字 2 用sizeof()函数&#xff0c;求出数组元素的个数 3 从键盘中任意输出一个数字m&#xff0c;…

Docker网络介绍

网络是虚拟化技术中最复杂的部分&#xff0c;也是Docker应用中的一个重要环节。 Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。 这些复杂情况的存在要求Docker有一个强大的网络功能去保障其网络的稳健性。因此&#xff0c;Docker…

象战----第十二届中山市邀请赛正赛

本次的题解一定让大家享受脑细胞碰撞与再生死亡的感受&#xff01;定然酣畅淋漓&#xff01;请耐心的读完 简称&#xff1a;让脑袋死机。。。 象战 老规矩先分析在打码&#xff1a; 注意到题目告诉我们&#xff1a;四个角落是不能放的 那么 我们设象在(i,j).(注意&#xff1a…

120.网络游戏逆向分析与漏洞攻防-邮件系统数据分析-邮件发送功能的封装

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

遍历二叉树和线索二叉树

目录 一、*遍历二叉树 1.1遍历定义 1.2遍历目的 1.3遍历用途 1.4遍历方法 1.4.1先序遍历&#xff08;DLR&#xff09; 1.4.2中序遍历&#xff08;LDR&#xff09; 1.4.3后序遍历&#xff08;LRD&#xff09; 1.5根据遍历序列确定二叉树 1.6遍历算法的实现 1.6.1先序遍…

MySQL—索引—基础语法

目录 一、创建、查看以及删除索引的语法 &#xff08;1&#xff09;创建索引 1、1会用到一个关键字&#xff1a;CREATE。 1、2增加索引还可以用到另外一个关键字——ALTER TABLE 表名 ADD INDEX ... 。 2、解释。 &#xff08;2&#xff09;查看索引 1、查看索引需要用到…

PCL 三次样条插值(二维点)

一、简介 在插值计算中,最简单的分段多项式近似应该是分段线性插值,它由连接一组数据点组成,仅仅只需要将这些点一一用直线进行顺序相连即可。不过线性函数插值的缺点也很明显,就是在两个子区间变化的比较突兀,也就是没有可微性(不够光滑)。因此我们需要更为符合物理情况…

Day58 代码随想录打卡|二叉树篇---将有序数组转换为二叉搜索树

题目&#xff08;leecode T108&#xff09;&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 方法&#xff1a;用有序数组构造平衡二叉搜索树&#xff0c;和我们之前有一题的思路差不多&#xff0c…

计算机毕设JAVA——学习考试管理系统(基于SpringBoot+Vue前后端分离的项目)

学习考试管理系统 概要系统架构技术运行环境系统功能项目演示图片 概要 网络上许多计算机毕设项目开发前端界面设计复杂、不美观&#xff0c;而且功能结构十分单一&#xff0c;存在很多雷同的项目&#xff1a;页面基本上就是套用固定模板&#xff0c;换个颜色、改个文字&#…

如何使用gprof对程序进行性能分析

如何使用gprof对程序进行性能分析 目录 1 gprof概述 2 gprof原理简述 3 gprof使用 3.1 gprof使用简述 3.2 gprof使用示例 4 小结 1 gprof概述 gprof 是 一个 GNU 的程序性能分析工具&#xff0c;可以用于分析C\C程序的执行性能。gprof工具可以统计出各个函数的调用次数、执…

C语言小例程

题目&#xff1a;两个乒乓球队进行比赛&#xff0c;各出三人。甲队为a,b,c三人&#xff0c;乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比&#xff0c;c说他不和x,z比&#xff0c;请编程序找出三队赛手的名单。 #include <stdio.h> #in…