タイミングタスクのスケジューリングスキーム
システム規模の発展に伴い、プロジェクトの組織構造や構造はますます複雑になり、業務範囲はますます広がり、スケジュールされたタスクの数は増加し、タスクはますます複雑になります。特にユーザーのニーズを満たすために、カレンダーが増加するとシステムが安定して動作するため、従来の垂直型プロジェクトであっても、主流の分散型プロジェクトであっても、サーバーを拡張してクラスターを形成することがよくあります。その後、タイミング タスクの要件は徐々に高くなり、現在の主流のプロジェクト アーキテクチャに基づくと、タイミング タスクは次の要件を満たす必要があります。
-
- 統合タスク管理。タスクを構成およびスケジュールするためのグラフィカル インターフェイスを提供します。
-
- タスク スケジューリングの冪等性を保証します(タスクの同時実行制御、同じタスクは同時に 1 つの実行しか許可されません)。
-
- タスクの柔軟な拡張により、混雑状況に応じてサーバーを動的に増減して負荷を分散し、大規模なタスクの断片化処理を実行できます。
-
- タスクの依存関係の問題は、タスクにサブタスクが含まれており、前のタスクが完了した後にサブタスクの実行がトリガーされるという状況に対処できます。
-
- 複数のタイプのタスクをサポートし、Spring Bean、Shell などをサポートします。
-
- タスクノードは可用性が高く、異常時やビジー時には他のノードに転送して実行することができます。
-
- ディスパッチ センターは可用性が高く、単一障害点を回避するためのクラスター展開をサポートしています。
-
- 実行ステータスの監視、タスクの実行ステータスを簡単に表示、異常事態アラーム、マルチチャネル通知をサポート。
#. 開発履歴:
テクノロジーの発展に伴い、スケジュールされたタスクは、シングル スレッド スケジューリングからマルチ スレッド スケジューリングに、単一マシンのデプロイメントからクラスター デプロイメントに、そして独立した実行からマルチタスクの共同実行に変わりました。
1. スレッド
JDK によって提供されるスレッド スリープを通じて実装されます。
private static int count = 0;
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while (count < 8) {
try {
Thread.sleep(1000);
System.out.printf("执行第:%d 次\n", ++count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
}
2. スレッドプール
JDK によって提供される遅延実行実装があります。
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 8; i++) {
ExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = new Runnable() {
@Override
public void run() {
++count;
System.out.printf("执行从 %d 次\n", count);
if (count > 7) {
System.exit(0);
}
}
};
// 也可以使用 ScheduledExecutorService.schedule
executorService.awaitTermination(1L, TimeUnit.SECONDS);
executorService.execute(runnable);
}
}
3.タイマータイムタスク
JDKにより提供され、主にモバイル端末(Android開発など)で利用されています。
private static int count = 0;
public static void main(String[] args) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.printf("执行第 %d 次\n", ++count);
if (count > 7) {
System.exit(0);
}
}
};
Timer timer = new Timer();
timer.schedule(timerTask, 500, 500);
}
4. スケジュール
Spring によって提供され、@EnableScheduling とともに使用されます
@Component
public class SpringScheduleTest {
private static int count;
@Scheduled(cron = "0/1 * * * * ?")
public void testSchedule() {
System.out.printf("执行第 %d 次\n", ++count);
}
}
cron 式: 秒-分-時-日-月-週-年
5.クォーツ
Maven に独立した依存関係があり、パッケージには SpringBoot2.0 が付属しています。
- 純粋な Maven プロジェクトの依存関係
<!-- 核心包 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <!-- 工具包 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.3.0</version> </dependency>
- SpringBoot2.0以降の依存関係
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
- テストクラス Test.java
public class Test { public static void main(String[] args) throws SchedulerException, ParseException { Scheduler factory = StdSchedulerFactory.getDefaultScheduler(); JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("tips", "去你大爷的"); JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class) .withIdentity("testJob", "testJobGroup") .setJobData(jobDataMap).build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("testTrigger", "testTriggerGroup") .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) .startNow().build(); factory.scheduleJob(jobDetail, trigger); factory.start(); } }
- タスククラス QuartzJob.java を作成する
public class QuartzJob implements Job { public static int count; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap(); String tips = jobDataMap.getString("tips"); System.out.printf("获取到参数:%s\n", tips); System.out.printf("执行第:%d 次\n", ++count); } }
6.Xxlジョブ
XXL-JOB は軽量の分散タスク スケジューリング プラットフォームであり、その中心的な設計目標は、迅速な開発、簡単な学習、軽量、簡単な拡張です。ソース コードは現在公開されており、そのまますぐに多くの企業のオンライン製品ラインに接続されています。
詳しい内容紹介については、資料アドレスをご確認ください。
-
ライブラリを作成し、テーブルを作成します。SQL ファイルはプロジェクト ディレクトリにあります: xxl-job-master/doc/db/tables_xxl_job.sql 注: そのデータベース名は xxl_job です。新しいライブラリを作成したくない場合は
、ただし、既存のライブラリにインポートする場合は、SQL ファイルを入力して名前を変更する必要があります。
-
プロジェクトを実行します: xxl-job-admin
-
プロジェクトの構造は次のとおりです。
-
mysql 接続構成を次のように変更します。
-
-
実行後、ブラウザで http://localhost:8080/xxl-job-admin にアクセスします。
デフォルトのアカウント: admin パスワード: 123456
-
ログインに成功したらディスパッチセンターに入ります
-
タスク実行者を登録するには、実行者サービスを個別に作成するか、既存のプロジェクト サービスに統合することができます。
以下は、新しい SpringBoot プロジェクトを作成する例です。- SpringBoot プロジェクトを作成し、依存関係を追加する
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.3.1</version> </dependency>
- resource ディレクトリに application.properties ファイルを作成します (yaml ファイルにも同じことが当てはまります。存在する場合は作成する必要はありません)。
# 执行器所在的服务的运行端口, 非执行器端口 server.port=8081 ### xxl-job admin address list, such as "http://address" or "http://address01,http://address02" # 注册地址, 这个地址其实就是部署或者运行完xxl-job-admin调度中心的浏览器访问地址 xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin ### xxl-job, access token xxl.job.accessToken=default_token ### xxl-job executor appname ### 执行器名称,需要配置到调度中心 xxl.job.executor.appname=xxl-job-executor ### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null xxl.job.executor.address= ### xxl-job executor server-info xxl.job.executor.ip= # 这个端口是执行器端口, 不是这个项目server.port 端口,也不能一样,否则会出现端口占用等错误信息 # 也就是说,执行器项目部署或者运行起来会有两个端口,如果是用docker部署,注意两个端口都要映射到宿主机端口 xxl.job.executor.port=9999 ### xxl-job executor log-path xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler ### xxl-job executor log-retention-days xxl.job.executor.logretentiondays=30
- 構成クラス XxlJobConfig.java を作成する
@Configuration 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() { 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; } }
- タスク (ジョブ) を作成します。バージョンが異なると表現が若干異なることに注意してください。
@Component public class SampleXxlJob { /** * 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); TimeUnit.SECONDS.sleep(2); } XxlJobHelper.handleSuccess("XXL-JOB:执行成功"); } }
- エグゼキュータを構成する
- 構成
- 成功
- 構成
- タスクを設定して実行する
-
構成タスク
-
一度実行する
-
ビュー・ログ
-
- SpringBoot プロジェクトを作成し、依存関係を追加する