Scheduler => Quartz => XXL-JOB => Apache Airflow
Contents
Prepare
npm i --save sleep
vim app.js
var http = require('http');
var url = require('url');
var sleep = require('sleep');
var server = http.createServer(function (req, res) {
var query = url.parse(req.url, true).query;
var start = new Date()
sleep.sleep(6);
var end = new Date()
res.end(`[${query.name}] ${start.getMinutes()}:${start.getSeconds()}-${end.getMinutes()}:${end.getSeconds()}`);
});
server.listen(process.argv[2]);
node app.js 8070
node app.js 8071
curl "http://localhost:8070?name=api1"
curl "http://localhost:8071?name=api2"
Scheduler
spring --version
# Spring CLI v2.0.6.RELEASE
spring init -b 2.0.6.RELEASE -dweb --build gradle SchedulerDemo && cd SchedulerDemo
vim src/main/java/com/example/SchedulerDemo/DemoApplication.java
package com.example.SchedulerDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
vim src/main/java/com/example/SchedulerDemo/DemoScheduler.java
package com.example.SchedulerDemo;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class DemoScheduler {
@Scheduled(cron = "0/10 * * * * ?")
public void task1() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8070?name=api1", String.class);
System.out.println(response.getBody());
}
}
./gradlew bootrun
[api1] 50:50-53:56
[api1] 50:0-54:6
[api1] 51:10-54:16
Concurrency
vim src/main/java/com/example/SchedulerDemo/DemoScheduler.java
package com.example.SchedulerDemo;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class DemoScheduler {
@Scheduled(cron = "0/10 * * * * ?")
public void task1() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8070?name=api1", String.class);
System.out.println(response.getBody());
}
@Scheduled(cron = "0/10 * * * * ?")
public void task2() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8071?name=api2", String.class);
System.out.println(response.getBody());
}
}
./gradlew bootrun
[api1] 52:0-52:6
[api2] 52:6-52:12
[api1] 52:12-52:18
[api2] 52:20-52:26
[api1] 52:26-52:32
[api2] 52:32-52:38
Async
vim src/main/java/com/example/SchedulerDemo/DemoScheduler.java
package com.example.SchedulerDemo;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
@EnableAsync
public class DemoScheduler {
@Async
@Scheduled(cron = "0/10 * * * * ?")
public void task1() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8070?name=api1", String.class);
System.out.println(response.getBody());
}
@Async
@Scheduled(cron = "0/10 * * * * ?")
public void task2() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8071?name=api2", String.class);
System.out.println(response.getBody());
}
}
./gradlew bootrun
[api2] 4:30-4:36
[api1] 4:30-4:36
[api2] 4:40-4:46
[api1] 4:40-4:46
[api2] 4:50-4:56
[api1] 4:50-4:56
Quartz
TODO
XXL-JOB
docker run --name xxl-job -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root_pwd -d mysql:5.7.17
git clone https://gitee.com/xuxueli0323/xxl-job && cd xxl-job
git checkout 2.2.0
docker exec -i xxl-job mysql -uroot -proot_pwd < ./doc/db/tables_xxl_job.sql
vim ./xxl-job-admin/src/main/resources/logback.xml
# <property name="log.path" value="./xxl-job-admin.log"/>
# IntelliJ IDEA
run XxlJobAdminApplication
spring --version
# Spring CLI v2.0.6.RELEASE
spring init -b 2.0.6.RELEASE -dweb --build gradle XXLJobDemo && cd XXLJobDemo
vim build.gradle
# implementation 'com.xuxueli:xxl-job-core:2.2.0'
vim src/main/java/com/example/XXLJobDemo/XXLJobHandler.java
package com.example.XXLJobDemo;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class XXLJobHandler {
@XxlJob("demoJobHandler")
public ReturnT<String> demoJobHandler(String param) throws Exception {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
XxlJobLogger.log("XXLJobHandler " + simpleDateFormat.format(new Date()));
return ReturnT.SUCCESS;
}
}
vim src/main/java/com/example/XXLJobDemo/XXLJobConfig.java
package com.example.XXLJobDemo;
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;
@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;
@Bean
public 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;
}
}
vim src/main/resources/application.properties
server.port=8081
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
xxl.job.accessToken=
xxl.job.executor.appname=xxl-job-executor-demo
xxl.job.executor.address=
xxl.job.executor.ip=
xxl.job.executor.port=9091
xxl.job.executor.logpath=./
xxl.job.executor.logretentiondays=30
./gradlew bootrun
-
浏览器打开http://localhost:8080/xxl-job-admin => 账号admin/123456
-
执行器管理 => 新增 => AppName=xxl-job-executor-demo/自动注册
-
任务管理 => 新增 => 执行器=执行器demo/Cron=0/30 * * * * ?/JobHandler=demoJobHandler => 操作:启动
-
调度日志 => 操作:执行日志
Apache Airflow
TODO
网友评论