校园网站建设意见表填写,广州开发区第二小学,网站举报网,设计制作小车教学视频一、后端xxl job的配置属性介绍 enabled #xff1a; 是否开启执行器#xff0c;如果为false#xff0c;调度中心就调用不了后端定时任务admin-addresses#xff1a;调度中心的地址#xff0c;多个则可以逗号拼接: url1,url2,url3access-token: 执行器通讯TOKEN ,必须和x…一、后端xxl job的配置属性介绍 enabled 是否开启执行器如果为false调度中心就调用不了后端定时任务admin-addresses调度中心的地址多个则可以逗号拼接: url1,url2,url3access-token: 执行器通讯TOKEN ,必须和xxl-job代码里面的一致 src/main/resources/application.yml 配置文件中 accessToken--- # xxljob系统配置
xxl:job:# 鉴权tokenaccessToken: xxl-job# 国际化i18n: zh_CN# 日志清理logretentiondays: 30triggerpool:fast:max: 200slow:max: 100appname: 执行器AppName, 配置完调度中心可以识别到 port: 执行器端口号执行器名称可以一致appname: xxl-job-executor但是如果多个执行器端口号必须区分开来 address: 执行器注册地址,默认自动获取IP ip: 执行器IP默认自动获取IPlogpath: 日志保存路径 logretentiondays: 日志保存天数 通过配置可以知道xxl-job 调度中心识别执行器的流程 开启执行器后执行器根据admin-addresses 地址和 xxl-job 注册到 调度中心并绑定执行器名称端口日志等信息 --- # xxl-job 配置
xxl.job:# 执行器开关enabled: true#enabled: false# 调度中心地址如调度中心集群部署存在多个地址则用逗号分隔。admin-addresses: http://localhost:9100/xxl-job-admin# 执行器通讯TOKEN非空时启用access-token: xxl-jobexecutor:# 执行器AppName执行器心跳注册分组依据为空则关闭自动注册appname: xxl-job-executor# 28080 端口 随着主应用端口飘逸 避免集群冲突port: 2${server.port}# 执行器注册默认IP:PORTaddress:# 执行器IP默认自动获取IPip:# 执行器运行日志文件存储磁盘路径logpath: ./logs/xxl-job# 执行器日志文件保存天数大于3生效logretentiondays: 30
测试启动调度中心和后台将后台注册到调度中心 启动xxx-job调度中心和 后台执行器 则可以看到注册成功 二、任务管理
2.1 常用配置 调度配置-调度类型一般我们默认选择CRON表达式可以参考文章cron 定时任务_cron 每月最后一天-CSDN博客任务配置-运行模式默认BEAN模式后面代码会演示 分片广播、命令行任务任务配置-JobHandler对应注解里面标注的名称 XxlJob(demoJobHandler) /*** 1、简单任务示例Bean模式*/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);}// default success} 高级配置-路由策略 第一个First总是选择注册列表中的第一个执行器执行。最后一个Last总是选择注册列表中的最后一个执行器执行。轮询Round按顺序轮流选择执行器执行实现简单负载均衡。随机Random随机选择一个执行器执行增加执行的不确定性。一致性HASHConsistent Hash通过Hash算法稳定地选择执行器即使执行器数量变化也能保持任务分配的连续性。最少使用Least UsedLFU或类似概念选择最近最少被使用的执行器以平衡负载。最近未使用Least Recently Used, LRU选择最久未被使用的执行器执行。故障转移Failover当首选执行器不可用时自动选择下一个可用的执行器。忙碌转移Busyover不仅考虑故障还考虑执行器的忙碌状态避免过载。分片广播Sharding Broadcast所有执行器都执行一次任务但每个执行器可以处理不同的数据分片适用于大数据量处理。 高级配置-阻塞处理策略 单机串行默认
描述任务按调度顺序一个接一个地执行前一个执行完再执行下一个。
特点简单但可能导致任务等待时间长。丢弃后续调度
描述如果执行器正忙新任务会被丢弃。
特点防止任务堆积但可能会丢失任务。覆盖之前调度
描述如果执行器正忙会中断当前任务立即执行新任务。
特点确保新任务快速执行但可能影响旧任务。 高级配置-任务超时时间 默认0, 表示不超时高级配置-失败重试次数 默认0, 表示不重试 三、 ruoyi-job 模块
ruoyi-job 是我们定义统一编写定时任务的子模块现在看看怎么编写第一个定时任务
引入依赖xxl-job核心包、已经公共common包 dependencies!-- 通用工具--dependencygroupIdcom.ruoyi/groupIdartifactIdruoyi-common/artifactId/dependency!-- xxl-job-core --dependencygroupIdcom.xuxueli/groupIdartifactIdxxl-job-core/artifactId/dependency/dependencies
1- 编写 XxlJobProperties ConfigurationProperties(prefix xxl.job) 映射 yml中的配置属性 Data
ConfigurationProperties(prefix xxl.job)
public class XxlJobProperties {private Boolean enabled;private String adminAddresses;private String accessToken;private Executor executor;DataNoArgsConstructorpublic static class Executor {private String appname;private String address;private String ip;private int port;private String logPath;private int logRetentionDays;}
} 2- 编写 XxlJobConfig 配置类
主要就是启动执行器并配置调度中心地址、token、执行器等等 注解解释 ConditionalOnProperty(prefix xxl.job, name enabled, havingValue true) 开启配置属性:xxl.job 中 enabled为true时候才会 注册 Bean注解标注的xxlJobExecutor 类 Slf4j
Configuration //标注配置类
EnableConfigurationProperties(XxlJobProperties.class) //启用配置属性
AllArgsConstructor
ConditionalOnProperty(prefix xxl.job, name enabled, havingValue true) //开启配置属性:enabled为true时候才会 注册xxlJobExecutor
public class XxlJobConfig {private final XxlJobProperties xxlJobProperties;Beanpublic XxlJobSpringExecutor xxlJobExecutor() {log.info( xxl-job config init.);// 初始化 xxl-job 执行器XxlJobSpringExecutor xxlJobSpringExecutor new XxlJobSpringExecutor();// 配置 调度中心地址xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());// 配置 tokenxxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());// 配置 执行器XxlJobProperties.Executor executor xxlJobProperties.getExecutor();//执行器相关属性xxlJobSpringExecutor.setAppname(executor.getAppname());xxlJobSpringExecutor.setAddress(executor.getAddress());xxlJobSpringExecutor.setIp(executor.getIp());xxlJobSpringExecutor.setPort(executor.getPort());xxlJobSpringExecutor.setLogPath(executor.getLogPath());xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());return xxlJobSpringExecutor;}}
3-编写定时任务 完成上面配置类便可以直接编写定时任务 Slf4j
Service
public class SampleService {/*** 1、简单任务示例Bean模式*/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);}// default success}
四、参数传递
更新任务时候设置参数如图 运行任务后台便可以接受到参数 XxlJob(demoJobHandler)public void demoJobHandler() throws Exception {XxlJobHelper.log(XXL-JOB, Hello World.);String jobParam XxlJobHelper.getJobParam();log.info(jobParam:{} , jobParam);for (int i 0; i 5; i) {XxlJobHelper.log(beat at: i);}// default success} 结果
2024-08-04 15:39:32 JRebel: Reconfiguring reprocessed bean sampleService [com.ruoyi.job.service.SampleService]
2024-08-04 15:39:36 [xxl-job, JobThread-1-1722757089189] INFO com.ruoyi.job.service.SampleService- jobParam:type1flagtrue 当然JSON也可以传递都后台按需求进行处理即可 2024-08-04 15:43:09 [xxl-job, EmbedServer bizThreadPool-1028558242] INFO c.x.job.core.executor.XxlJobExecutor- xxl-job regist JobThread success, jobId:1, handler:com.xxl.job.core.handler.impl.MethodJobHandler6146a40f[class com.ruoyi.job.service.SampleService#demoJobHandler]
2024-08-04 15:43:09 [xxl-job, JobThread-1-1722757389734] INFO com.ruoyi.job.service.SampleService- jobParam:{“type”:1,code:0} 五、轮询策略
前置场景启动2个端口不一样的执行器8080和8081端口则会在2个注册的节点上轮流访问 总结 执行器交替执行减少服务器压力实现负载均衡如果一个节点挂了则会交给另一个节点处理 六、分片广播 场景如果我们要同时通知1万个对象当前有5个执行器采用轮询则要循环1万次所以此场景就应该采用分片广播策略 新增分片广播任务 后台处理 对分片总是进行取余模拟分片执行 /*** 2、分片广播任务*/XxlJob(shardingJobHandler)public void shardingJobHandler() throws Exception {// 分片索引int shardIndex XxlJobHelper.getShardIndex();// 分片总数int shardTotal XxlJobHelper.getShardTotal();//循环10次模拟分片广播for (int i 0; i 10; i) {//取余模拟分片执行if (i % shardTotal shardIndex) {XxlJobHelper.log(第 {} 片, 命中分片开始处理, i);}}} 执行结果 执行新增分片广播任务生成2条调用日志 分别查看日志内容 分片0执行了第 0、4、6、8任务 分片1执行了第 1、3、5、7、9任务 这样对比轮询去处理该场景任务极大的提升了任务处理的速度 分片广播的应用场景 数据处理任务如对大量数据进行清洗、分析、转换等操作可以将任务拆分成多个小任务分布式地执行。分布式计算任务如对大规模数据进行机器学习、深度学习等计算可以将计算任务拆分成多个小任务分布式地执行加速计算过程。并发请求任务如对多个服务进行并发请求可以将请求拆分成多个小请求分布式地执行提高请求的并发处理能力。 注意事项 在实现分片广播任务时需要确保执行器集群中的执行器回调地址xxl.job.admin.addresses保持一致。同一个执行器集群内的AppNamexxl.job.executor.appname也需要保持一致。在任务执行过程中需要考虑并发执行的情况确保任务逻辑的正确性。 总之XXL-JOB的分片广播功能为分布式任务调度提供了一种高效、灵活的实现方式适用于多种需要并行处理的任务场景。 七、命令行任务 演示window下执行命令行linux也是一样的 1-先新记事本建文件 mkdir.bat文件,内容如下 命令行执行命令新建一个文件夹yyyy-MM-dd HH-mm-ss 作为文件夹名称 echo off
setlocal enabledelayedexpansion:: 获取当前日期
for /f tokens2-4 delims/- %%a in (date /t) do (set YY%%cset MM%%aset DD%%b
):: 获取当前时间
for /f tokens1-3 delims: %%h in (time /t) do (set HH%%hset MM%%iset SS%%j
):: 格式化日期和时间字符串以适应文件夹名
set folderName%YY%-%MM%-%DD%_%HH%-%MM%-%SS%
:: 创建文件夹
md D:\CPanFiles\download\!folderName!
2-创建调度任务 任务运行参数为上面mkdir.bat文件的地址我放在D盘downlad文件夹下面 3-commandJobHandler 运行命令行后台如下获取定时任务参数执行命令行 XxlJob(commandJobHandler)public void commandJobHandler() throws Exception {//1-获取参数String command XxlJobHelper.getJobParam();int exitValue -1;BufferedReader bufferedReader null;try {// commandProcessBuilder 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));// 记录到日志表String line;while ((line bufferedReader.readLine()) ! null) {XxlJobHelper.log(line);}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);}}
前台点击执行任务生成文件夹成功 八、HTTP平台请求 这里模拟发送请求到百度 httpJobHandler 后台拿到参数发送HTTP请求返回请求结果 XxlJob(httpJobHandler)public void httpJobHandler() throws Exception {// param parseString param XxlJobHelper.getJobParam();if (param null || param.trim().length() 0) {XxlJobHelper.log(param[ param ] invalid.);XxlJobHelper.handleFail();return;}//获取http请求参数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();}}//校验参数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 发送http请求HttpURLConnection connection null;BufferedReader bufferedReader null;try {// connectionURL realUrl new URL(url);connection (HttpURLConnection) realUrl.openConnection();// connection settingconnection.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;charsetUTF-8);connection.setRequestProperty(Accept-Charset, application/json;charsetUTF-8);// do connectionconnection.connect();// dataif (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 获取http状态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);}}}
执行结果跳转到百度登录页面 9-生命周期 XxlJob(value demoJobHandler2, init init, destroy destroy) init 当 XXL-JOB 框架启动并加载此任务时会尝试调用标注了 XxlJob 注解的类中的 init 方法如果存在 这可以用于执行一些初始化操作比如资源加载、数据库连接初始化等 destroy 当 XXL-JOB 框架停止或卸载此任务时会尝试调用标注了 XxlJob 注解的类中的 destroy 方法如果存在这可以用于执行一些清理操作比如关闭数据库连接、释放资源等。 XxlJob(value demoJobHandler2, init init, destroy destroy)public void demoJobHandler2() throws Exception {XxlJobHelper.log(XXL-JOB, Hello World.);}public void init() {log.info(init);}public void destroy() {log.info(destory);}
十、报警邮件配置 1-以qq邮箱举例接受错误报警提醒进入到安全设置页面右上角 2-生成授权码 3-后台配置下 授权码上面生成的 以及 邮箱账号 --- # 邮件配置
spring:mail:from: 13361831qq.comhost: smtp.qq.comusername: 13361831qq.com# 邮箱授权码password: ixxxj0000jfoghbihport: 25properties:mail:smtp:auth: truesocketFactory:class: javax.net.ssl.SSLSocketFactorystarttls:enable: truerequired: true 4- 创建定时任务绑定邮箱 执行任务结果收到信息成功