任务调度

一、学习途径

餐前小甜点

  • 编程不良人

https://www.bilibili.com/video/BV15K4y1C7Bb/?spm_id_from=333.788.recommend_more_video.3

原理

  • 图灵-4小时

https://www.bilibili.com/video/BV1Nz4y11755/?spm_id_from=333.788.recommend_more_video.0

进阶-xxl-Job

  • 动力节点—2小时

https://www.bilibili.com/video/BV1gJ41117zo?from=search&seid=15360937579315747294

随便看看吧-评价还行

  • 吹牛皮

https://www.bilibili.com/video/BV1WE411f7St?from=search&seid=15360937579315747294

二、Timer

1、一个 new Timer() 一条线程

public class TestSchedule {/*** 参数说明: 原子型的,线程安全,多任务的时候会出现线程等待* 1、定时任务* 2、开始时间* 3、周期执行任务的间隔时间  ,默认为0* 它会开启一条新的线程执行定时任务*/public static void main(String[] args) {test1();}/*** 每隔两秒执行一次* Fri Mar 19 10:26:39 CST 2021task1* Fri Mar 19 10:26:41 CST 2021task1* Fri Mar 19 10:26:43 CST 2021task1* Fri Mar 19 10:26:45 CST 2021task1*/public static void test1() {// new 的时候 timer就启动了Timer timer = new Timer();// schedule 只是任务的添加timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println(new Date() + "task1");}}, new Date(), 2000);}/*** 间隔时间<任务执行时间,那么间隔时间无效* Fri Mar 19 10:28:45 CST 2021start* Fri Mar 19 10:28:48 CST 2021end* Fri Mar 19 10:28:48 CST 2021start* Fri Mar 19 10:28:51 CST 2021end* Fri Mar 19 10:28:51 CST 2021start* Fri Mar 19 10:28:54 CST 2021end*/public static void test2() {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(3000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}/*** 间隔时间<任务执行时间,那么间隔时间=间隔时间-任务执行时间* Fri Mar 19 10:30:28 CST 2021start* Fri Mar 19 10:30:29 CST 2021end* Fri Mar 19 10:30:30 CST 2021start* Fri Mar 19 10:30:31 CST 2021end* Fri Mar 19 10:30:32 CST 2021start* Fri Mar 19 10:30:33 CST 2021end*/public static void test3() {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(1000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}/*** 多线程 线程之间无影响*/public static void test4() {Timer timer = new Timer();Timer timer2 = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(1000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);timer2.schedule(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start2");Thread.sleep(1000);System.out.println(new Date() + "end2");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}}

2、测试scheduleAtFixedRate与schedule 没啥区别呀?

package com.example.不良人.timer;import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;/*** copyright (C), 2021,北京同创永益科技发展有限公司** @author xiaodi* @version 1.0.0* <author>              <time>                 <version>                   <description>* xiaodi               2021/3/19 上午 10:23:39           1.0.0                      测试Schedule* @program base* @description 测试Schedule* @create 2021/3/19 上午 10:23:39*/
public class TestScheduleAtFixeRate {public static void main(String[] args) {test3();}/*** 每隔两秒执行一次* Fri Mar 19 10:36:28 CST 2021task1* Fri Mar 19 10:36:30 CST 2021task1* Fri Mar 19 10:36:32 CST 2021task1* Fri Mar 19 10:36:34 CST 2021task1* Fri Mar 19 10:36:36 CST 2021task1*/public static void test1() {Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println(new Date() + "task1");}}, new Date(), 2000);}/*** 间隔时间<任务执行时间,那么间隔时间无效* Fri Mar 19 10:37:51 CST 2021start* Fri Mar 19 10:37:54 CST 2021end* Fri Mar 19 10:37:54 CST 2021start* Fri Mar 19 10:37:57 CST 2021end* Fri Mar 19 10:37:57 CST 2021start* Fri Mar 19 10:38:00 CST 2021end*/public static void test2() {Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(3000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}/*** 间隔时间<任务执行时间,那么间隔时间=间隔时间-任务执行时间* Fri Mar 19 10:38:44 CST 2021start* Fri Mar 19 10:38:45 CST 2021end* Fri Mar 19 10:38:46 CST 2021start* Fri Mar 19 10:38:47 CST 2021end* Fri Mar 19 10:38:48 CST 2021start* Fri Mar 19 10:38:49 CST 2021end*/public static void test3() {Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(1000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}/*** 多线程 线程之间无影响*/public static void test4() {Timer timer = new Timer();Timer timer2 = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start");Thread.sleep(1000);System.out.println(new Date() + "end");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);timer2.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {try {System.out.println(new Date() + "start2");Thread.sleep(1000);System.out.println(new Date() + "end2");} catch (InterruptedException e) {e.printStackTrace();}}}, new Date(), 2000);}}

3、使用线程池

public class TimerPool {public static void main(String[] args) {final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);Timer timer = new Timer();for (int i = 0; i < 2; i++) {timer.schedule(new Mytask("task" + i), new Date(), 2000);}}
}/*** 任务类*/
class Mytask extends TimerTask {private String name;public Mytask(String name) {this.name = name;}@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + "-" + this.name + "start");Thread.sleep(3000);System.out.println(Thread.currentThread().getName() + "-" + this.name + "end");} catch (InterruptedException e) {e.printStackTrace();}}
}

三、Springboot+定时任务

1、开启定时任务后线程问题

Springboot中默认开启的是单线程。多个定时任务的时候会相互阻塞

可以设置线程池的大小

https://blog.csdn.net/zhoudingding/article/details/109326166

2、基本使用

不管是否是同一个类中的定时任务都用同一条线程

MyTask

@Configuration
@EnableScheduling
public class MyTask {// 同一个类中公用同一个线程//秒 分 时 天 月 周 年//spring 整合 定时任务 年默认为忽略的@Scheduled(cron = "0/1 * * * * ? ")public void Task1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + "task1");Thread.sleep(5000);}@Scheduled(cron = "0/2 * * * * ? ")public void Task2() {System.out.println(Thread.currentThread().getName() + "task2");}
}

MyTask2

@Configuration
@EnableScheduling
public class MyTask2 {// 不同一个类中公用同一个线程//秒 分 时 天 月 周 年//spring 整合 定时任务 年默认为忽略的@Scheduled(cron = "0/1 * * * * ? ")public void Task1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + "task2-1");}@Scheduled(cron = "0/2 * * * * ? ")public void Task2() {System.out.println(Thread.currentThread().getName() + "task2-2");}
}

3、设置多线程

@Configuration
public class SchedulingConfig {@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();// 设置线程池的大小taskScheduler.setPoolSize(10);return taskScheduler;}
}

四、xxl-job

1、项目下载地址

xuxueli:

注意版本问题

​ github:https://github.com/xuxueli/xxl-job

​ gitee:https://gitee.com/zhanglovefish/xxl-job/tree/master/

我学习的是2.3.0版本 handler以及改成@Component+@Bean的形式了,不影响。

推荐大家先看一遍README.md文件再开始学习

2、任务调度器集群部署

1、修改jvm参数让其成为两个服务

web端口:8081 8082

执行器端口:9999 9990—————— 一定要核对配置文件中的执行器端口后启动

同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表

2、启动

启动后会自动注册

3、架构图

4、路由策略测试

FIRST(第一个):固定选择第一个机器;
LAST(最后一个):固定选择最后一个机器;
ROUND(轮询):;
RANDOM(随机):随机选择在线的机器;
CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

3、调度中心可以集群部署

1、把调度中心打两个包

一个为8080 一个为8088

2、注册逻辑图

任务1,2,3 会通过nginx反向代理进行注册到调度中心上

3、修改host文件

表示我请求 www.job.com 时就是请求127.0.0.1

4、配置nginx

# 配置两个调度中心
upstream xxl-job-admin {server 127.0.0.1:8080;server 127.0.0.1:8088;
}
#————————————————————————————————
# 转发到xxl-job-admin
location /xxl-job-admin {proxy_pass http://xxl-job-admin;
}

5、启动两台调度中心

java -jar xxl-job-admin-2.3.1-SNAPSHOT-8080.jar
java -jar xxl-job-admin-2.3.1-SNAPSHOT-8088.jar

6、访问测试是否正常

http://localhost:8080/xxl-job-admin/
http://localhost:8088/xxl-job-admin/# 测试域名访问是否成功
http://www.job.com/xxl-job-admin/xxl-job-admin/

7、设置任务执行器的注册地址

8、启动两个任务执行器

启动后的截图

9、任务调度接口图

在任务调度的过程中:

调用的时候只有一台在工作。当8080故障后,8088才会工作

五、如何在自己的项目中开发

1、添加maven依赖

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

2、配置文件信息

# web port
server.port=9091
# no web
#spring.main.web-environment=false
# log config
logging.config=classpath:logback.xml
### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
xxl.job.executor.appname=xxl-job-executor-sample
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
xxl.job.executor.ip=
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=9999
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=30

3、配置XxlJobConfig

package com.xxl.job.executor.core.config;import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 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;}/*** 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;**      1、引入依赖:*          <dependency>*             <groupId>org.springframework.cloud</groupId>*             <artifactId>spring-cloud-commons</artifactId>*             <version>${version}</version>*         </dependency>**      2、配置文件,或者容器启动变量*          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'**      3、获取IP*          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();*/}

4、创建handler接口

package com.xxl.job.executor.service.jobhandler;import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;/*** XxlJob开发示例(Bean模式)* <p>* 开发步骤:* 1、任务开发:在Spring Bean实例中,开发Job方法;* 2、注解配置:* 为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称",* init = "JobHandler初始化方法",* destroy = "JobHandler销毁方法")",* 注解value值对应的是调度中心新建任务的JobHandler属性的值。* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;* 如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;** @author xuxueli 2019-12-11 21:52:51*/
@Component
public class SampleXxlJob {private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);/*** 1、简单任务示例(Bean模式)*/@XxlJob("demoJobHandler-linux-normal")public void demoJobHandler() throws Exception {// 0、获取参数String command = XxlJobHelper.getJobParam();System.err.println("从任务调度上获取的参数:" + command);// 1、获取job的id为1System.out.println("jobId=" + XxlJobHelper.getJobId());// 2、job回调日志XxlJobHelper.log("任务执行了");// 3、返回执行结果// 成功——不写默认为成功!XxlJobHelper.handleSuccess("任务执行成功");// 超时// XxlJobHelper.handleTimeout("任务执行超时了");}/*** 2、分片广播任务*/@XxlJob("shardingJobHandler")public void shardingJobHandler() throws Exception {// 分片参数int shardIndex = XxlJobHelper.getShardIndex();int shardTotal = XxlJobHelper.getShardTotal();XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);// 业务逻辑for (int i = 0; i < shardTotal; i++) {if (i == shardIndex) {XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);} else {XxlJobHelper.log("第 {} 片, 忽略", i);}}}/*** 3、命令行任务*/@XxlJob("commandJobHandler")public void commandJobHandler() throws Exception {String command = XxlJobHelper.getJobParam();int exitValue = -1;BufferedReader bufferedReader = null;try {// command processProcessBuilder 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));// command logString line;while ((line = bufferedReader.readLine()) != null) {XxlJobHelper.log(line);}// command exitprocess.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");}}/*** 4、跨平台Http任务* 参数示例:* "url: http://www.baidu.com\n" +* "method: get\n" +* "data: content\n";*/@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;}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();}}// param validif (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");// requestHttpURLConnection connection = null;BufferedReader bufferedReader = null;try {// connectiondemoJobHandler2URL 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;charset=UTF-8");connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-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 StatusCodeint statusCode = connection.getResponseCode();if (statusCode != 200) {throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");}// resultbufferedReader = 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);}}}/*** 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;*/@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")public void demoJobHandler2() throws Exception {XxlJobHelper.log("XXL-JOB, Hello World.");}public void init() {logger.info("init");}public void destroy() {logger.info("destory");}}

5、设计思想

 将调度行为抽象成“调度中心”公共平台,而平台自身并不承担业务逻辑,"调度中心"负责发起调度请求。将任务抽象成分散的JobHandler,交给”执行器“统一管理,”执行器“负责接收调度请求并执行对应的JobHandler中业务逻辑。因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统不再受限于任务模块;支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持简括调度结果以及执行日志,支持执行器Failover(故障转移)

六、分布式多实例部署方案

架构图

七、搭建中遇到的问题

时区的问题

时区不一致导致调度紊乱,日志无法正常查看

# centOS
# 查看当前时区
date -R
# 修改当前时区
tzselect
依次选择 Asia->China->Beijing Time->Yes
输入:5-9-1-1
# 修改/etc/profile
vi /etc/profile
# 添加
TZ='Asia/Shanghai'
export TZ='CST-8'
# 刷新
source /etc/profile
# 再次查看时间结果
date -R

执行器名称问题

名称不能太长,长了不执行(-_-)

任务调度-xxl-job相关推荐

  1. PHP工程师技能清单

    PHP应用广泛,作为一个PHPer,你需要的不仅仅是PHP本身,你需要的是一个技术生态,包括Java.Golang.Javascript.Python这里有你应该知道的工具和知识 以下列出的都是我作为 ...

  2. xxl子任务_阿里面试官:聊一下分布式任务调度有那些解决方案?

    作者:黄兆平 来源:http://blog.freshfood.cn/article/39 # 简介 随着系统规模的发展,定时任务数量日益增多,任务也变得越来越复杂,尤其是在分布式环境下,存在多个业务 ...

  3. xxl子任务_XXL-JOB v2.0.2,分布式任务调度平台 | 多项特性优化更新

    v2.0.2 Release Notes 1.底层通讯方案优化:升级较新版本xxl-rpc,由"JETTY"方案调整为"NETTY_HTTP"方案,执行器内嵌n ...

  4. xxl子任务_XXL-JOB v2.1.2 发布,分布式任务调度平台

    v2.1.2 Release Notes 1.方法任务支持:由原来基于JobHandler类任务开发方式,优化为支持基于方法的任务开发方式:因此,可以支持单个类中开发多个任务方法,进行类复用 @Xxl ...

  5. 分布式定时任务调度系统技术选型--转

    http://www.expectfly.com/2017/08/15/%E5%88%86%E5%B8%83%E5%BC%8F%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1% ...

  6. python建站部署_SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台...

    SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台 一.概述 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源 ...

  7. python任务调度平台 界面_分布式任务调度平台XXL-JOB

    以前带我的人说过,最好的学习就是看官方文档,个人也有4个T的学习视频,但是会发现讲的都是入门,有的也比较浅. 官方文档比较官方,也比较权威,打开xxl-job的官网,写的贼详细,有些人喜欢收博客,不喜 ...

  8. 轻量级分布式任务调度平台 XXL-JOB

    From:https://www.cnblogs.com/xuxueli/p/5021979.html github 地址 及 中文文档地址:https://github.com/xuxueli/xx ...

  9. 3千字带你搞懂XXL-JOB任务调度平台

    思维导图 文章已收录Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary 一.概述 在平时的业务场景中,经常有一些场景需要使用定时任 ...

  10. 分布式任务调度平台一站式讲解

    文章目录 一.传统的定时任务 1. 传统的定时任务存在那些缺点 2. 定时任务集群幂等性问题 二.传统定时任务的实现方案 2.1. 多线程 2.2. TimeTask 2.3. 线程池 2.4. Sp ...

最新文章

  1. 最新!国内芯片70个细分领域重要代表企业 VS 国外
  2. 可遇不可求的BUG之采用MYSQL odbc 3.51访问数据库返回值缺失
  3. python输入完怎么运行-如何在服务器上跑python程序
  4. Elasticsearch 存储模型
  5. idea中如何创建servlet文件
  6. Mysql默认隔离级别为什么是可重复读?
  7. bootstrap网格系统_如何使用Bootstrap网格系统?
  8. 消息中间件学习总结(12)——Kafka与RocketMQ的多Topic对性能稳定性的影响比较分析
  9. svg如何平铺 html5,如何在HTML5中使用SVG
  10. Java(31)_JDBC连接mysql数据库(一)
  11. 论文笔记_S2D.66_ICRA_2021_LVI-SAM: 紧耦合的激光视觉惯导SLAM系统
  12. 小米路由R1D固件升级后导致Misstar tools插件页面显示错误解决方法
  13. 开源办公系统:支持在线Office在线编辑、文档协同
  14. 记录每日习题(35)
  15. 网络安全认证与加密协议算法整合
  16. 软件测试可用性测试方法,几种常用的可用性测试的方法
  17. 图解网络:组建一个网络需要哪些网络设备和安全设备
  18. relay_log_purge参数一则
  19. js对大数据量的处理
  20. [990]Geohash算法原理及实现

热门文章

  1. JUC包都有哪些内容
  2. 史上最全储能系统优缺点梳理
  3. android执行.sh,android中调整cpu频率以及执行sh文件简单记录
  4. Stream流获取(集合,数组)
  5. 审批工作流—ccflow
  6. 模拟计算MS软件常见问题及解答(一)
  7. C 语言 大小写字母转换程序
  8. WS2812灯珠(四)---实现全彩呼吸灯效果
  9. 信息学奥林匹克竞赛python_什么是USACO?来了解下美国信息学奥林匹克竞赛!
  10. cad2023-autocad2023