はじめに: 前回の記事では、Springboot 統合 Quartz フレームワークを実際のプロジェクトに適用する方法について書きました。ただし、Quartz フレームワークにはいくつかの欠点があるため、xxl-job はこれらの欠点を完全に克服でき、現在市場に出ている比較的大規模なタイミング タスク フレームワークでもあります。xxl-job は、スケジュールされたすべてのタスクの統合設定と管理のためのディスパッチ センター コンソール ページを提供します。前回の記事では、ディスパッチ センターを構築する詳細なプロセスを書きました: https://blog.csdn.net/qq798867485/article/details/131415408。xxljob を使用するには、派遣センターがサービスを提供する必要があるため、構築方法がわからない学生は、最初に構築することができます。
1. xxl-jobを統合する
xxljob の依存関係を導入する
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
xxljob設定をymlに追加します。
xxl:
job:
admin:
# 调度中心服务部署的地址
addresses: http://localhost:8022/xxl-job-admin
# 执行器通讯TOKEN,要和调度中心服务部署配置的accessToken一致,要不然无法连接注册
accessToken: default_token777
executor:
# 执行器AppName
appname: job-demo
# 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
address:
ip:
#执行器端口号:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 8889
# 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath:
# 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
logretentiondays: 30
springboot プロジェクトの開始時にディスパッチング センター サービスに接続するための構成クラスを追加します。
XxlJobConfig.java
package com.example.xxjob.config;
import com.example.xxjob.job.DemoHandler;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
@Configuration
@Slf4j
public class XxlJobConfig {
@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() {
log.info(">>>>>>>>>>> start 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);
log.info(">>>>>>>>>>> end xxl-job config init. >>>>>>>>");
return xxlJobSpringExecutor;
}
}
springboot アプリケーションを起動すると、xxl-job ディスパッチ センターに接続できることがわかります。
2. スケジュールされたタスクを作成します (パラメータなし)
実際の業務におけるサービス層クラスの呼び出しをシミュレートするサービス層クラスを作成する
package com.example.xxjob.service;
public interface UserService {
void demoJob();
}
package com.example.xxjob.service.impl;
import com.example.xxjob.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service("userService")
@Slf4j
public class UserServiceImpl implements UserService {
@Override
public void demoJob() {
log.info(">>>>>>>>>> 开始处理实际业务逻辑 >>>>>>>>>>>>>>>");
log.info(">>>>>>>>>> 完成处理实际业务逻辑 >>>>>>>>>>>>>>>");
}
}
2.1 BEAN モード (クラス形式) (非推奨)
Bean モードのタスクはクラスベースの開発をサポートしており、各タスクは Java クラスに対応します。
- 利点: プロジェクト環境を制限せず、互換性が高い。main メソッドによって直接開始されたプロジェクトなど、フレームワークのないプロジェクトでもサポートを提供できます。
- 欠点:
- 各タスクは Java クラスを占有する必要があるため、クラスが無駄になります。
- タスクの自動スキャンと実行コンテナへの注入はサポートされていないため、手動で注入する必要があります。
また、非常に悪い欠点もあります。つまり、@Autowired または @Resource を使用して Bean を注入することはできません。使用しないと、null ポインター例外が報告されます。
2.1.1 新しいスケジュールされたタスクを作成する
package com.example.xxjob.job;
import com.example.xxjob.service.UserService;
import com.example.xxjob.service.impl.UserServiceImpl;
import com.xxl.job.core.handler.IJobHandler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DemoHandler extends IJobHandler {
private final UserService userService = new UserServiceImpl();
@Override
public void execute() throws Exception {
log.info(">>>>>>>>>> BEAN模式(类形式) 开始 >>>>>>>>>>>>>>>");
userService.demoJob();
log.info(">>>>>>>>>> BEAN模式(类形式) 成功 >>>>>>>>>>>>>>>");
}
}
2.1.2 エグゼキュータコンテナへの手動注入
XxlJobExecutor.registJobHandler("demoHandler", new DemoHandler());
2.1.3 ディスパッチセンターのエグゼキュータ管理へ – エグゼキュータ (つまり、アプリケーション) を追加します。
AppName: 和项目中yml文件配置的appname 的值一致
名称: 测试应用
注册方式:
-- 自动注册:就无需配置ip和端口
-- 手动录入:需要把你项目中的ip(域名)和端口录入
2.1.3 ディスパッチセンターのタスク管理に移動 – スケジュールされたタスク (つまり、プロジェクト内のスケジュールされたタスク) を追加します。
执行器:定时任务所在的项目,跟上一步执行器的名称一致
调度类型:Core
core表达式:根据需求中定时任务实际情况定
运行模式: BEAN
JobHandler:demoHandler,跟注入到执行器容器名称一致
剩下的一些选项可以默认,也可以根据你实际情况定。
2.1.4 スケジュールされたタスクを実行し、ログを表示する
2.2 BEANモード(メソッド形式)(推奨)
2.2.1 新しいスケジュールされたタスクを作成する
package com.example.xxjob.job;
import com.example.xxjob.service.UserService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DemoJob {
@Autowired
private UserService userService;
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
log.info(">>>>>>>>>> BEAN模式(类形式) 开始 >>>>>>>>>>>>>>>");
userService.demoJob();
log.info(">>>>>>>>>> BEAN模式(类形式) 成功 >>>>>>>>>>>>>>>");
}
}
2.2.2 以降の手順は「2.1 BEANモード(クラス形式)」と同様で、スケジュールされたタスクを追加して実行します。
3. スケジュールされたタスクの移行 (オプション)
この要件は、会社の元のプロジェクトで使用されている時限タスク フレームワークが Quartz であることですが、現在はすべての時限タスクを管理するために xxl-job を統合するように変更する必要があります。
まず、ディスパッチ センターを展開する必要があります。構成と新しいエグゼキュータは前の手順と同じです。ここでの違いは、パラメータを渡すことで実行できる時間指定タスクを定義することです。
時間指定タスクを実行するロジックを理解し、複数のハンドラー メソッドの定義を減らします。
時限タスクハンドラーを作成する
@XxlJob("doJob")
@Transactional(rollbackFor = Exception.class)
public void doJob(){
String jobParam = XxlJobHelper.getJobParam();
try {
if(StrUtil.isNotBlank(jobParam)){
JSONObject jsonObject = JSONObject.parseObject(jobParam);
if(Objects.nonNull(jsonObject)){
Object bean = SpringUtils.getBean(jsonObject.getString("bean"));
Method method = bean.getClass().getMethod(jsonObject.getString("method"));
logger.info("调度定时任务执行开始:{}",jobParam);
method.invoke(bean);
logger.info("调度定时任务执行结束:{}",jobParam);
}
}
}catch (Exception e){
logger.info("调度定时任务执行失败:{},原因是:{}",jobParam,e.getMessage());
XxlJobHelper.handleFail();
}
}
タスクをバッチで追加します (パラメーターを使用)
JobHeadler: doJob
任务参数:{"bean":"userService","method":"demoJob"}
bean:为原先定时任务的类,method:为原先定时任务的方法
完全なプロジェクトのコード: https://github.com/gorylee/learnDemo