xxl-job(2.3.0)分布式任务bean模式,GLUE shell调度实践,源码debug

2023-11-21 14:10

本文主要是介绍xxl-job(2.3.0)分布式任务bean模式,GLUE shell调度实践,源码debug,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、xxl-job分布式任务调度入门参考

1.分布式任务调度平台XXL-JOB官网文档
2.其它简单入门案例

二、调度中心简单的源码修改

1.源码git clone http://gitee.com/xuxueli0323/xxl-job
2.修改配置文件,修改了MYSQL EMAIL配置,新增钉钉配置。配置文件多环境支持application-test.properties、application-prod.properteis(通过启动脚本参数-Dspring.profiles.active=test指定,见Dockerfile文件内的JVM参数),这里的配置项不多,使用环境变量方式配置也可以
在这里插入图片描述
3.新增的钉钉报警类DingdingJobAlarm,还可以扩展其它的

@Component
@ConditionalOnProperty(name = "alarm.dingding.enable",havingValue = "true")
public class DingdingJobAlarm implements JobAlarm {private final RestTemplate restTemplate = new RestTemplate();@Value("${alarm.dingWebhook}")private String dingWebhook;@Overridepublic boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {StringBuilder content = new StringBuilder("任务调度异常报警:").append("{任务名称:").append(info.getJobDesc()).append(",执行器名称:").append(info.getExecutorHandler()).append(",执行器ip:").append(jobLog.getExecutorAddress()).append(",任务参数:").append(jobLog.getExecutorParam()).append(jobLog.getTriggerMsg());HashMap<String, String> cmap = new HashMap<>(2);cmap.put("content", content.toString());HashMap<String, Object> map = new HashMap<>(4);map.put("msgtype", "text");map.put("text", cmap);ResponseEntity<Object> responseEntity = restTemplate.postForEntity(dingWebhook, map, Object.class);HttpStatus httpStatus = responseEntity.getStatusCode();return httpStatus.is2xxSuccessful() && ((LinkedHashMap)responseEntity.getBody()).get("errcode").equals(0);}}

4.修改Dockerfile
基础镜像改为FROM java:8(主要为了减少磁盘空间占用),增加JVM参数:JAVA_OPTS等(指定profile读取不同的配置文件),新增Dockerfile-prod(正式环境打镜像用)

FROM java:8
MAINTAINER ksc
ENV PARAMS=""
ENV TZ=PRC
ENV JAVA_OPTS -Dname=$JAR_NAME -server -Dspring.profiles.active=test -Xmx800m -Xms800m -Xmn250m -Xss256k -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/oom-dump -XX:CMSFullGCsBeforeCompaction=2 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80  -XX:MetaspaceSize=150m -XX:MaxMetaspaceSize=150m -Duser.timezone=GMT+8
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD target/xxl-job-admin-*.jar /app.jar
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]

4.执行数据脚本(/doc/db里面)
5.注释掉父pom中的三个plugin:GPG,javadoc,Source否则jenkin构建镜像时可能出错(流程:mvn+Dockerfile构建镜像,push到nexus3等镜像仓库,ssh免密登录执行远程命令拉取镜像启动容器)
6.配置nginx转发(略)

三、集成到微服务

特别特别特别注意:xxl-job不仅可以替换spring schedule,quatz,还可以替换linux crontab服务器脚本任务,如磁盘清理,数据备份等,参考(GLUE SHELL/PYTHON等),如果需要这方面支持,微服务就不能容器化部署,否则GLUE SHELL脚本任务执行环境是docker容器内。。。

1.新增依赖

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

2.新增xxl-job配置类


/*** xxl-job config** @author xuxueli 2017-04-28*/
@Configuration
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.appname}")private String appname;@Value("${xxl.job.executor.address}")private String address;@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;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}}

3.job业务类,注意2.2.0->2.3.0有些不兼容

@Component
@Slf4j
public class SampleXxlJob {/*** 1、简单任务示例(Bean模式)* !!!依赖xxl-job-core版本<=2.2.0时*/@XxlJob("demoJobHandler")public ReturnT<String> execute(String param) throws Exception {log.info("xxxxxxxxxxxxxxxxx:"+param);for (int i = 0; i < 5; i++) {TimeUnit.SECONDS.sleep(2);}return ReturnT.FAIL;}/*** 1、简单任务示例(Bean模式)* !!!依赖xxl-job-core版本>=2.3.0时* *     @XxlJob("demoJobHandler")*     public void demoJobHandler() throws Exception {*         XxlJobHelper.log("XXL-JOB, Hello World.");*         for (int i = 0; i < 5; i++) {*             XxlJobHelper.log("beat at:" + i);*             TimeUnit.SECONDS.sleep(2);*         }*     }* * */}

4.新增配置

xxl:job:accessToken: ''admin.addresses: http://xxx.xxx.cn/xxl-job-adminexecutor:appname: myapp1 #这个类似namespace作资源隔离的,一个调度调度中心可以同时调度N个执行器address: ''ip: ''port: 9993   #这个在微服务里暴露出来的一个netty server端口,调度中心通过该端口调度这个执行器里定义的所有任务logpath: /xxxxxx/xxl-job/jobhandlerlogretentiondays: 10

四、bean模式与glue shell模式使用示例

1.配置执行器,这里的appName对应yml配置的appName
在这里插入图片描述
2.bean模式,关键是jobHandler对应 @XxlJob(“cancelPayTimeoutOrder”)
在这里插入图片描述

@Component
public class SampleXxlJob {/*** 1、简单任务示例(Bean模式)*/@XxlJob("cancelPayTimeoutOrder")public void cancelPayTimeoutOrder(String param) throws Exception {try {//业务代码System.out.println("调度中心传来的任务参数:"+param);int a=1/0;}catch (Exception e){//注意这里需要手动设置失败,调度中心才能把本次任务标记为失败,并触发告警XxlJobHelper.handleFail("xxxxx");}}

3.GLUE SHELL服务器脚本任务
新建好任务后,进入WEB IDE编写shell脚本即可(其它脚本基本一样的),注意如果任务执行异常,需要返回1,调度中心才会标记该任务为失败并触发告警
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210130001844232.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5NTA2OTc4,size_16,color_FFFFFF,t_70

五、基本原理,详见官方文档

在这里插入图片描述

六、源码debug

从调度中心手动触发“执行一次”调度开始,断点调试执行器端的业务流程,首先进入的是执行器端xxl-job-core的内置服务(该EmbedServer基于netty,端口就是xxl.job.executor.port,服务启动后xxl-job-core内的注册线程会将该服务地址注册到调度中心。XxlJobSpringExecutor impliment SmartInitializingSingleton,XxlJobSpringExecutor在XxlJobConfig配置,实例化该类后便启动netty server)
1.执行器端即接受到调度中心的http请求
在这里插入图片描述
2.根据uri路由到executorBiz的不同业务
在这里插入图片描述
3.把该请求存入XXljobExcutor内的jobThreadRepository(一个ConcurrentHashMap<Integer, JobThread>,key为jobId),jobThreadRepository就是一个线程池,当接收调度中心的任务调度请求,根据jobId去jobThreadRepository获取JobThread。
在这里插入图片描述
4.然后将本次调度请求参数triggerParam存入该JobThread定义的TriggerQueue
在这里插入图片描述
5.JobThread每3s去TriggerQueue取出调度任务进行执行
在这里插入图片描述

6.执行完后,通过TriggerCallbackThread 发起Http请求告知调度中心本次调度结果。调度中心根据该任务配置判断进行执行器路由及发起重试与否,是否触发告警,最终结果存入mysql用于日志查看,调度报告查看等
在这里插入图片描述

七、关于高可用

根据调度原理,执行器内置在业务应用里,业务应用多实例集群部署即可保证HA。调度中心通过http请求执行器触发任务调度业务逻辑,如果调度中心挂了便无法触发调度业务逻辑。调度中心多实例集群部署需要保证使用的同一一个mysql库,同一个时刻多个xxl-job-admin实例向触发器发起任务调度需要先到mysql注册一个DB锁(分布式锁),注册成功的才能向执行器发起调度

这篇关于xxl-job(2.3.0)分布式任务bean模式,GLUE shell调度实践,源码debug的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/402814

相关文章

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Java实现远程执行Shell指令

《Java实现远程执行Shell指令》文章介绍使用JSch在SpringBoot项目中实现远程Shell操作,涵盖环境配置、依赖引入及工具类编写,详解分号和双与号执行多指令的区别... 目录软硬件环境说明编写执行Shell指令的工具类总结jsch(Java Secure Channel)是SSH2的一个纯J

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service