XxlJob深度性能优化实践

news2024/11/15 21:45:15

一、背景

天画项目的数据工厂目前在与xxl-job对接自动化数据生成任务,另外我司也在使用该组件做业务,所以想深入了解下XxlJob。在跟进了社区的github等仓库issue发现开发迭代停滞了一段时间,思来想去准备开个下游分支做一些性能优化和特性开发等,于是fork了下源码,将其作为天画社区关于任务调度的组件来使用。
我花了几天阅读源码,同时做了一些简单的调试,发现了一些问题之后着手进行优化,本文将从XxlJob的原理出发深入其性能瓶颈,并提出一些解决方案。相关优化的代码已经上传至gitee.

二、调度流程解读

在进行性能和安全改造之前,需要对xxljob的调度执行原理要非常了解,所以这里我们先简单看一下xxljob的调度流程和线程模型。

2.1 调度流程

  1. 服务端启动流程

xxlJob服务端启动流程.png

  1. 客户端启动流程

客户端启动流程 (2).png

  1. 客户端与服务端交互流程

客户端与服务端交互流程 (1).png

2.2 调度线程模型

通过上面的流程图我们可以梳理出如下服务端和客户端用到的线程和线程池,具体作用通过名称即可了解。
服务端:

  1. 触发器线程池(fastTriggerPool,slowTriggerPool)
  2. 注册&停止注册线程池(registryOrRemoveThreadPool)
  3. 注册监听线程(registryMonitorThread)
  4. 任务失败监听线程(monitorThread)
  5. 任务完成回调线程池(callbackThreadPool)
  6. 任务完成回调监听线程(monitorThread)
  7. 统计日志线程(logrThread)
  8. 调度线程(scheduleThread)
  9. 时间轮线程(ringThread)

客户端:

  1. http 交互监听线程(thread)
  2. 注册器线程(registryThread)
  3. 任务线程(JobThread)
  4. 任务回调日志线程(triggerCallbackThread)
  5. 回调日志重试线程(triggerRetryCallbackThread)

2.3 客户端API

这里需要说明的是,在一定程度上客户端(也就是执行器,以下统称为客户端)也会作为服务端接受调度中心(即xxl job server 服务端)的回调,所以这里是一个比较令人迷惑的地方。
这里列出服务端调用客户端的API
127.0.0.1:9999/beat
127.0.0.1:9999/idleBeat
127.0.0.1:9999/run
127.0.0.1:9999/kill
127.0.0.1:9999/log

2.4 服务端API

这里列出客户端调用服务端的API
127.0.0.1:8080/api/callback
127.0.0.1:8080/api/registry
127.0.0.1:8080/api/registryRemove

三、潜在问题

在反复看了xxljob 开源社区gitee/github上的issue之后,我对下面的几个问题比较关注,所以在业余时间中专门调试并且进行了一定的复现,这里简单回顾一下xxljob在高并发调度过程中可能产生的问题。

3.1 重复调度

重复调度的问题其实是偶发问题,问题的现象或者特征就是一个任务在一次调度中重复执行了两次,同时产生了 两条xxljob log,发生时间相同。

3.2 安全问题

xxljob控制台查询客户端日志的时候会返回accessToken,github上的issue讨论已经提供了复现步骤,这里目前作者已经提供升级,但是本文的重点不止于此,因为另外的安全问题就是accessToken在客户端与服务端之间的交互是明文传输的,另外也是服务端与所有客户端共用的,一旦泄露其实会比较危险。

3.3 并发调度变慢

XxlJob的调度在并发变高的时候从日志上可以看出调度会有一些延迟,出现这个问题的原因有以下几个方面:

  1. 一秒内调度量比较多,对客户端和服务端在一秒内会产生上千次调度
  2. 调度粒度是线程(JobThread)和单次粒度的,所以一秒内要处理2-3倍的数据库IO和网络IO
  3. 选用了busyover或者failover的调度策略,这两种需要在调度之前给对应的客户端发送心跳
  4. 日志处理,这里包括客户端的日志处理和服务端的日志处理,在并发比较高的情况下日志产生的量也比较大,

对调度业务会产生一定的资源占用。

3.4 线程模型的性能瓶颈

这个问题其实与3.3类似,从上面的调度流程图可以看到xxljob其实是对每个xxl_job_info在对应的客户端上构建一个JobThread,如果执行器对应的任务比较多且存在一秒内并发触发的话就可能导致客户端本身出现性能问题。

3.5 回调并发变慢

这个问题也是高并发调度下产生的问题,xxljob在日志处理上有两种方式:一种是在调度job方法内通过XxlJobHelper.log去记录产生的业务日志,这部分是存在于客户端的,另外一种则是调度日志,即对该job在当前调度结果的日志信息推送到服务端做记录或者统计,这部分数据存储在服务端的xxl_job_log表中。
在高并发调度的情况下,客户端的处理存在性能问题,一次回调推送的日志太少,客户端存在积压。

3.6 分页性能问题

在高并发或者大量任务的场景中xxlJob的管理控制台在任务管理和调度日志分页上存在性能问题,可能导致页面加载缓慢同时服务端进程崩溃,进而影响服务运行。

四、优化点

4.1 认证优化

在xxl job的源码中需要借助xxl.job.accessToken来完成客户端与服务端的认证,这个配置在客户端注册到服务端,以及客户端和服务端在相互调用过程中都会进行认证。由于配置是统一的,所以所有客户端都需要配置这个,另外认证过程中是accessToken是明文传输的,所以这种认证机制一定程度上是比较弱的。另外如果改动认证机制的话则客户端和服务端都要改,本次优化则花一定的精力来提升安全性。总结起来就是如下几点:

  1. 强制安全认证

客户端或者服务端不配置accessToken则启动失败

  1. 认证加密

客户端与服务端之间的交互均通过加密accessToken的方式

  1. 弱化accessToken在认证过程中的影响

对于每个客户端虽然都配置同样的accessToken,但是新生成的accessToken(原accessToken+appName)则是通过AES进行加密。
这里我们看一下进行强认证过程的时序图:

xxljob强认证方式 (1).png
下面我们看一下具体实现源码:
客户端:

 private String  initEmbedServer(String address, String ip, int port, String appname, String accessToken) throws Exception {

        // fill ip port
        port = port>0?port: NetUtil.findAvailablePort(9999);
        ip = (ip!=null&&ip.trim().length()>0)?ip: IpUtil.getIp();


        // generate address
        // registry-address:default use address to registry , otherwise use ip:port if address is null
        if (address==null || address.trim().length()==0) {
            String ip_port_address = IpUtil.getIpPort(ip, port);
            address = "http://{ip_port}/".replace("{ip_port}", ip_port_address);
        }

        // accessToken
        if (accessToken == null || accessToken.trim().length()==0) {
            throw new IllegalArgumentException("xxl-job accessToken need not  null. ");
            //logger.warn(">>>>>>>>>>> xxl-job accessToken is empty. To ensure system security, please set the accessToken.");
        }

        // start
        embedServer = new EmbedServer();
        //accessToken加密
        String accessCookie &#

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

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

相关文章

环境配置:ROS melodic安装turtlebot

文章目录 1.已有的环境2.安装2.1.首先cd进入到catkin_ws文件夹,然后输入以下命令行:2.2.将turtlebot加入环境2.3.选择性安装其它依赖包2.4.运行turtlebot in stage [perfect] 1.已有的环境 在之前已经配置好了小乌龟的前提下,我们已经拥有了…

2024/2/4 备战蓝桥杯 5-1 前缀和

目录 求和 0求和 - 蓝桥云课 (lanqiao.cn) 可获得的最小取值 0可获得的最小取值 - 蓝桥云课 (lanqiao.cn) 领地选择 P2004 领地选择 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 求和 0求和 - 蓝桥云课 (lanqiao.cn) 思路:先对公式进行合并同类相&#x…

AVR 328pb触摸功能基本介绍和使用

AVR 328pb触摸功能基本介绍和使用 📝ATMEGA328PB-AU外设中带外围触摸控制器(PTC)电容式触摸按钮、滑块和轮子24个自帽通道和144个互帽通道。(ATMEGA328P没有的) ✅PTC-外围触摸控制器 🍃低功耗、高灵敏度、…

图形界面基础

X Window System 什么是 X Window System? 最初是1984年麻省理工学院的研究,之后变成UNIX、类UNIX、以及OpenVMS等操作系统所一致适用的标准化软体工具套件及显示架构的运作协定。X Window系统透过软体工具及架构协定来建立操作系统所用的图形用户界面&a…

Flink SQL Client 安装各类 Connector、Format 组件的方法汇总(持续更新中....)

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

Redis-布隆过滤器解决穿透详解

本文已收录于专栏 《中间件合集》 目录 背景介绍概念说明原理说明解决穿透安装使用安装过程Redis为普通安装的配置方式Redis为Docker镜像安装的配置方式 具体使用控制台操作命令说明Spring Boot集成布隆过滤器 总结提升 背景介绍 布隆过滤器可以帮助我们解决Redis缓存雪崩的问题…

算法笔记刷题日记——3.简单入门模拟 3.2 查找元素

刷题日记 3.2 查找元素 B1041 B1004 B1028 B1032 A1011 A1006 A1036 错题记录 B1028 人口普查 某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的,但不一定是合理的…

Javascript入门学(基础)

软件篇 JS基础语法第一天 1.javascript介绍 1.1 js是什么 是什么 是一种运行在客户端(浏览器)的编程语言,实现人机交互效果,而html和css是标记性语言,并非编程语言有什么用 js的组成 htmlcssjs实现按钮点击功能 …

使用mmrotate对自定义数据集进行检测

这里写自定义目录标题 安装虚拟环境创建与准备安装mmrotate 自定义数据集标注数据与格式转换数据集划分与大图像切片 训练与测试修改配置文件执行训练进行测试鸣谢 安装 mmrotate是一个自带工作目录的python工具箱,个人觉得,在不熟悉的情况下&#xff0…

node.js后端+小程序前端+mongoDB(增删改查)

前言 今天我对比了以下node.js的express与python的fastAPI,我决定我还是出一期关于node.jsmangoDB小程序的小案例吧。 不是python的fastAPI不好用,因为fastAPI是python较新的技术,我不敢果断发出教学文章(这件事情还是留着给pyt…

Leetcode—59. 螺旋矩阵 II【中等】

2024每日刷题&#xff08;113&#xff09; Leetcode—59. 螺旋矩阵 II 实现代码 class Solution { public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> ans(n, vector<int>(n));int num 0;int c1 0, c2 n - 1;int r1 …

探索C语言结构体:编程中的利器与艺术

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 常量与变量 1. 什么是结构体 在C语言中本身就自带了一些数据类型&#x…

Verilog刷题笔记21

题目&#xff1a; A priority encoder is a combinational circuit that, when given an input bit vector, outputs the position of the first 1 bit in the vector. For example, a 8-bit priority encoder given the input 8’b10010000 would output 3’d4, because bit[4…

假期算法提升(带你彻底掌握滑动窗口)

呀哈喽&#xff0c;我是结衣。 今天我们要学习的是一种新的算法&#xff0c;也是一种双指针。不过他拥有一个全新的名字”滑动窗口“。 文章目录 1.长度最小的子数组&#xff08;medium&#xff09;思路解题方法Code 2.无重复字符的最长子串&#xff08;medium&#xff09;思路…

【WebSocket】微信小程序原生组件使用SocketTask 调用星火认知大模型

直接上代码 微信开发者工具-调试器-终端-新建终端 进行依赖安装 npm install base-64 npm install crypto-js 然后顶部工具栏依次点击 工具-构建npm // index.js const defaultAvatarUrl https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQ…

[ECE] P2.3Determine t_P_LH and t_P_HL from the oscilloscope

The terms t_P_LH and t_P_HL​​ refer to the propagation delays associated with the low-to-high and high-to-low transitions in a digital signal. These delays are essential in digital systems and are measured with respect to the voltage levels. (Low-to-High…

挑战杯 python+深度学习+opencv实现植物识别算法系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的植物识别算法研究与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;4分 &#x1f9ff; 更多…

js数组和字符串之间的转换方式以及数组的一些方法

一、数组和字符串之间的转换方式 1&#xff09;将字符串切割成字符串数组—stringObject.split(separator, howmany) seperator-----字符串、正则表达式&#xff0c;必需 howmany------指定返回的数组的最大长度&#xff0c;可省略&#xff0c;省略后全量返回 源代码 var str&q…

node-red通过指令方式读取DL/T645-2007通信协议数据

node-red通过指令方式读取DL/T645-2007通信协议数据 一、DL/T645-2007通信协议介绍1.1 DL/T645通信链路1.2 DL/T645-2007数据格式1.3 CS校验码生成算法1.4 返回数据解析1.5 返回数据处理 二、node-red实现 参考链接&#xff1a; DLT645-2007电表协议解析DL/T645-2007通信协议应…

TDengine用户权限管理

Background 官方文档关于用户管理没有很详细的介绍&#xff0c;只有零碎的几条&#xff0c;这里记录下方便后面使用。官方文档&#xff1a;https://docs.taosdata.com/taos-sql/show/#show-users 1、查看用户 show users;super 1&#xff0c;表示超级用户权限 0&#xff0c;表…