この記事では、最初のインターネット技術の生体内マイクロチャネル公共番号に登場し
たリンク:https://mp.weixin.qq.com/s/l4vuYpNRjKxQRkRTDhyg2Q
著者:陳Wangrong
業界で広く使用の分散スケジューリングフレームワークは、ほぼすべての主要なアプリケーションに必要なツール、この記事では、使用タスクスケジューリングフレームワークの需要や痛みのポイントの背景を説明し、オープンソースの使用は、分散タスクスケジューリングフレームワークは、実際に探求し、分析されていますフレームワークと彼らのビジネスの思考のこれらのタイプの長所と短所。
ビジネスの背景
なぜ1.1時限タスクスケジューリングを使用する必要があります
(1)時間駆動処理シナリオ:クーポン、更新毎日利益、リフレッシュタグデータと人口データ毎日の全体のポイントを送信します。
(2)データの処理バッチ:月次統計レポートデータバッチ、バッチ更新のステータスメッセージ、少ないリアルタイムを要求。
(3)非同期実行デカップリング:アクティブリフレッシュ、オフラインクエリの非同期実行、及び内部ロジックデカップリング。
1.2ニーズや痛みのポイント
(1)機能に警告監視タスクを実行します。
(2)タスクを柔軟に再起動することなく、動的に構成することができます。
(3)サービスの透明性、低い結合、合理構成は、開発を容易にします。
(4)テスト容易性。
(5)可用性、単一障害点のありません。
(6)タスクを繰り返し、異常なロジックを防止するために、実行されません。
分散並列処理能力(7)大きな課題。
第二に、練習や探査のためのオープンソースのフレームワーク
2.1 Java 原生 Timer 和ScheduledExecutorService
2.1.1タイマーの使用
タイマー欠陥:
-
タイマーは、すべてのタスクが実際にシリアル実行されることを意味し、複数のタスクを処理するために、シングルスレッドの下タイマーで、遅延の前のタスクは、にした後、ミッションに影響します。
-
シングルスレッド理由は、実行時に定期的なタスクと、未処理の例外が生成されるため、だけでなく、現在のスレッドは、すべてのスケジュールされたタスクが停止します停止します。
- タイマータスクの実行には、絶対時間システムに依存して、変更が計画の実施につながるシステム時刻を変更します。
以上により欠陥に、タイマーを使用しないようにしよう、という考えも明確に使用ScheduledThreadPoolExecutorの代替タイマー、プロンプトが表示されます。
2.1.2 ScheduledExecutorService使用
タイマ欠陥ScheduledExecutorServiceを修復し、すべての内部ScheduledExecutorService実装の第一は、同時に複数のタスクをサポートすることができるScheduledThreadPoolスレッドプールです。
異常なタスクの実行が発生し、治療が加えScheduledExecutorServiceで、タスクを実行する他のスレッドには影響しませんのために一つのスレッドが実行をシステム時刻の変更に伴う変更はありません、遅延時間間隔に基づいています。
もちろん、ScheduledExecutorServiceも独自の制限があります。唯一のタスクスケジューリングの遅延に応じて行うことが、絶対時間とカレンダーベースのスケジューリングのニーズを満たすことができません。
2.2春のタスク
2.2.1春タスクの使用
タスク春のフレームスプリングが他の追加パッケージに依存しない軽量なタイミングタスク独立して開発され、構成が簡単です。
ここでは、アノテーションを使用した構成
2.2.2春タスクの欠陥
春のタスク自体は永続性をサポートしていない、何の公式発表に分散クラスタモデルが存在しない、開発者は手動でのみビジネスアプリケーションに拡張を達成するために自分自身に頼ることができ、視覚的、簡単な構成のニーズを満たすことができません。
2.3永遠のクラシッククォーツ
2.3.1基本的な導入
クォーツフレームワークは、最も有名なオープンソースのJavaフィールドタスクのスケジューリングツールで、現在デファクトスタンダード通常の作業で、ほぼすべてのオープン・ソース・フレームワークは、石英コアのスケジュールに基づいて構築され、時限タスクです。
2.3.2原理は解決しました
コアコンポーネントとアーキテクチャ
キーコンセプト
(1)スケジューラ:タスクスケジューラは、タスク制御を実行するようにスケジュールされています。本質的に、コンテナの計画とスケジューリング、登録、すべてのトリガーがJobDetail対応する、タスクの基本的なコンポーネントとして実行するスレッドプールを使用し、効率を向上させる作業です。
(2)トリガ:関数、トリガービルダー強力なCronTriggerのcron式に基づいているタスクがトリガーされたときに通知するためにタスクスケジューリング、タスクスケジューラを定義するためのトリガ時間ルール、。
(3)カレンダー:特定の時間のカレンダー収集ポイント。トリガーカレンダーの複数を含むことができる、時間の特定のポイントを除外または含めるために使用されてもよいです。
(4)JobDetail:実行可能なジョブは、そのような名前のジョブとして実装クラスジョブ情報及び他の関連する静的情報を記述するために使用される、などリスナー。
(5)職業:タスク実行インターフェイスは、唯一の真のビジネスロジックを実行するための方法を実行します。
(6)JobStore:タスク・ストレージ、主RAMJobStoreとJDBCJobStoreは、RAMJobStore JVMは、メモリに格納され、損失のリスクと、JDBCJobStoreタスク情報をデータベースに保持されている限られた数の、クラスタリングのためのサポートがあります。
2.3.3説明練習
(1)石英の基本的な使用に
- クォーツは、公式ドキュメントやハンズオンチュートリアルオンラインのブログを参照してくださいすることができます。
(2)ダイナミックなビジネスユースに応えると、再起動が失われていない変更するには、一般的に保存するデータベースを使用する必要があります。
-
クォーツ自体がJDBCJobStoreをサポートしていますが、より多くのその構成データテーブルは、公式の推奨設定は公式文書を参照することができ、10の以上のテーブル、業務用重いです。
- 使用中のほとんどのニーズを満たすために、ときにのみ対応するタスクの実行ログと関連テーブルの基本的な構成とトリガを必要があります。
(3)アセンブリの
- 石英動的タスク設定情報がデータベースに永続化、パックデータ項目間の使用のための実質的にジャーパッケージするように動作する、のみ依存JARパッケージおよび構成データ・テーブルに対応する組み込まれたアイテムの参照は、透明な石英が配置使用することが可能です。
拡張(4)
-
クラスタモード
、することができないデータベースのロック機構によって実行されるタスクの一意性を保証するために、高可用性のミッションのためにフェールオーバーと負荷分散によって達成するが、クラスタリングは単にHA、ノードの数が増加するための機能と、単一のタスクの効率を増強しません水平展開を図ります。
-
クォーツプラグ
このような増大し、タスク実行ログ、シリアル処理タスク依存シナリオ、基準をトリガするなど、特定のニーズのために拡張することができる:クォーツウィジェット-シリアルタスクスケジューリングを間
2.3.4欠陥や不備
(1)サービス・データ・テーブルに永続タスク情報を必要とし、ビジネスが結合されています。
同じプロジェクト内の(2)スケジューリングロジックと実行論理共存は、機械の定着性能場合には、必然的に互いとスケジューリング動作に影響を与えます。
(3)水晶クラスターモデルでは、独自に、タスクの実行をデータベースタスクの排他ロックを取得し、メカニズムのバランスを完璧な負荷を達成しなかったです。
2.4軽量アーティファクトXXL-JOB
2.4.1基本的な導入
XXL-JOBは軽量分散タスクスケジューリングプラットフォームであり、軽量、シンプルな学習、拡張コードが続けて更新しやすい主な機能、導入のしやすさ、急速な発展のプラットフォームです。
「コントロールセンターは、」タスクのスケジューリングコンソールで、プラットフォーム自体は、ビジネスロジックを負担しますが、一元管理およびタスクの実装を担当スケジューリング、およびタスク管理プラットフォームを提供していない、「アクチュエータ」スケジューリングと実行の「コントロールセンター」を受信する責任があり、5月直接展開アクチュエータ、アクチュエータは、既存のビジネスのプロジェクトに統合することができます。スケジュールとタスク制御タスク実行デカップリングすることで、ビジネスはビジネスロジックの開発に関わる使用する必要があります。
いくつかの主要な機能モジュールは、動作モードの様々なサポートし、ルーティングポリシーは、単純なスライスデータは、機械のアクチュエータクラスタに対応する数に基づく処理することができるだけでなく、スケジュール・ログなどとして主に動的構成管理タスク、タスクの監視および統計レポートを提供します。
2.4.2原理は解決しました
問い合わせコンポーネントをスケジューリング開始以来スケジューリングモジュールは、石英コアフレームワーク、バージョン2.1.0に基づいて前2.1.0バージョン、石英依存性、時間ラウンドスケジュールを取り除きます。
2.4.3説明練習
参照の詳細な構成やプレゼンテーション公式文書。
2.4.3.1デモの使用:
例1:単純な作業の構成は、唯一の継承IJobHandler抽象クラス、および宣言ノートを必要とします
@JobHandler(値=「offlineTaskJobHandler」)、ビジネスロジックを実装することができます。(注:ダボの導入後に導入)。
@JobHandler(value="offlineTaskJobHandler")
@Component
public class OfflineTaskJobHandler extends IJobHandler {
@Reference(check = false,version = "cms-dev",group="cms-service")
private OfflineTaskExecutorFacade offlineTaskExecutorFacade;
@Override
public ReturnT<String> execute(String param) throws Exception {
XxlJobLogger.log(" offlineTaskJobHandler start.");
try {
offlineTaskExecutorFacade.executeOfflineTask();
} catch (Exception e) {
XxlJobLogger.log("offlineTaskJobHandler-->exception." , e);
return FAIL;
}
XxlJobLogger.log("XXL-JOB, offlineTaskJobHandler end.");
return SUCCESS;
}
}
例2:フラグメンテーション放送タスク。
@JobHandler(value="shardingJobHandler")
@Service
public class ShardingJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
// 分片参数
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
// 业务逻辑
for (int i = 0; i < shardingVO.getTotal(); i++) {
if (i == shardingVO.getIndex()) {
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
} else {
XxlJobLogger.log("第 {} 片, 忽略", i);
}
}
return SUCCESS;
}
}
2.4.3.2統合ダボ
ダボスプリングブートスタータとビジネスファサードジャーパッケージの依存関係を導入する(1)。
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.demo.service</groupId>
<artifactId>xxx-facade</artifactId>
<version>1.9-SNAPSHOT</version>
</dependency>
(2)消費プロファイルがダボ端構成を添加した(環境に応じて切り替えることによって、プロファイル、複数のプロファイルを定義します)。
## Dubbo 服务消费者配置
spring.dubbo.application.name=xxl-job
spring.dubbo.registry.address=zookeeper://zookeeper.xyz:2183
spring.dubbo.port=20880
spring.dubbo.version=demo
spring.dubbo.group=demo-service
(3)の正面インターフェースは、コード@Referenceを通して注入しました。
@Reference(check = false,version = "demo",group="demo-service")
private OfflineTaskExecutorFacade offlineTaskExecutorFacade;
(4)プログラムを追加@EnableDubboConfigurationコメントを開始します。
@SpringBootApplication
@EnableDubboConfiguration
public class XxlJobExecutorApplication {
public static void main(String[] args) {
SpringApplication.run(XxlJobExecutorApplication.class, args);
}
}
2.4.4視覚的な設定作業
組み込みプラットフォームのプロジェクトの開発者は、タスク管理・実行ログの監視を容易にし、機能をテストするためにいくつかの簡単なを提供します。
拡張2.4.5
(1)モニターし、最適化レポートにタスク。
そのような警報中心として拡張(2)アラームタスクは、内部メッセージ、SMSアラートを提供するために添加されます。
(3)異なるモニタアラームと異常な状況下では、再試行戦略の実行は、実際の内部動作に現れます。
2.5可用性弾仕事
2.5.1基本的な導入
弾ジョブスケジューリングは、2つの独立したサブ弾ジョブ・ライトと弾ジョブ・クラウドのコンポーネントで構成され、分散ソリューションです。
弾ジョブ-Liteは、軽量の非中枢ソリューションとして位置付けタスクの分散協調サービスを提供するために、フォームのjarパッケージを使用します。
弾ジョブ・クラウドは、追加のリソース管理、アプリケーションの配布、およびプロセスの分離やその他のサービスを提供し、Mesos +ドッカーソリューションを使用して。
残念ながら反復は更新レコードに2年を持っていません。
2.5.2原理は解決しました
2.5.3説明練習
2.5.3.1デモの使用
(1)インストールの飼育係、レジストリの設定を構成し、コンフィギュレーションファイル、レジストリZKの設定を追加します。
@Configuration
@ConditionalOnExpression("'${regCenter.serverList}'.length() > 0")
public class JobRegistryCenterConfig {
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter(@Value("${regCenter.serverList}") final String serverList,
@Value("${regCenter.namespace}") final String namespace) {
return new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
}
}
spring.application.name=demo_elasticjob
regCenter.serverList=localhost:2181
regCenter.namespace=demo_elasticjob
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=user
spring.datasource.password=pwd
(2)を、添加したデータソースの設定とプロファイルデータソースの構成を設定します。
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
@Bean
@Primary
public DataSource getDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=user
spring.datasource.password=pwd
(3)は、イベントの設定を設定します。
@Configuration
public class JobEventConfig {
@Autowired
private DataSource dataSource;
@Bean
public JobEventConfiguration jobEventConfiguration() {
return new JobEventRdbConfiguration(dataSource);
}
}
(4)異なるタスクのトリガイベントの柔軟な構成を容易にするためには、ElasticSimpleJobコメントを結合します。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ElasticSimpleJob {
@AliasFor("cron")
String value() default "";
@AliasFor("value")
String cron() default "";
String jobName() default "";
int shardingTotalCount() default 1;
String shardingItemParameters() default "";
String jobParameter() default "";
}
(5)設定を初期化します。
@Configuration
@ConditionalOnExpression("'${elaticjob.zookeeper.server-lists}'.length() > 0")
public class ElasticJobAutoConfiguration {
@Value("${regCenter.serverList}")
private String serverList;
@Value("${regCenter.namespace}")
private String namespace;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private DataSource dataSource;
@PostConstruct
public void initElasticJob() {
ZookeeperRegistryCenter regCenter = new ZookeeperRegistryCenter(new ZookeeperConfiguration(serverList, namespace));
regCenter.init();
Map<String, SimpleJob> map = applicationContext.getBeansOfType(SimpleJob.class);
for (Map.Entry<String, SimpleJob> entry : map.entrySet()) {
SimpleJob simpleJob = entry.getValue();
ElasticSimpleJob elasticSimpleJobAnnotation = simpleJob.getClass().getAnnotation(ElasticSimpleJob.class);
String cron = StringUtils.defaultIfBlank(elasticSimpleJobAnnotation.cron(), elasticSimpleJobAnnotation.value());
SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(JobCoreConfiguration.newBuilder(simpleJob.getClass().getName(), cron, elasticSimpleJobAnnotation.shardingTotalCount()).shardingItemParameters(elasticSimpleJobAnnotation.shardingItemParameters()).build(), simpleJob.getClass().getCanonicalName());
LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration.newBuilder(simpleJobConfiguration).overwrite(true).build();
JobEventRdbConfiguration jobEventRdbConfiguration = new JobEventRdbConfiguration(dataSource);
SpringJobScheduler jobScheduler = new SpringJobScheduler(simpleJob, regCenter, liteJobConfiguration, jobEventRdbConfiguration);
jobScheduler.init();
}
}
}
(6)上記、ダボを統合するビジネスロジックを完了記載の方法に従ってインターフェイスを実装SimpleJob。
@ElasticSimpleJob(
cron = "*/10 * * * * ?",
jobName = "OfflineTaskJob",
shardingTotalCount = 2,
jobParameter = "测试参数",
shardingItemParameters = "0=A,1=B")
@Component
public class MySimpleJob implements SimpleJob {
Logger logger = LoggerFactory.getLogger(OfflineTaskJob.class);
@Reference(check = false, version = "cms-dev", group = "cms-service")
private OfflineTaskExecutorFacade offlineTaskExecutorFacade;
@Override
public void execute(ShardingContext shardingContext) {
offlineTaskExecutorFacade.executeOfflineTask();
logger.info(String.format("Thread ID: %s, 作业分片总数: %s, " +
"当前分片项: %s.当前参数: %s," +
"作业名称: %s.作业自定义参数: %s"
,
Thread.currentThread().getId(),
shardingContext.getShardingTotalCount(),
shardingContext.getShardingItem(),
shardingContext.getShardingParameter(),
shardingContext.getJobName(),
shardingContext.getJobParameter()
));
}
}
2.6ゆう開元フレーム
(1)土星:土星は、それが弾性仕事に基づいて変換された、唯一の製品は、ソースに分散タスクスケジューリングプラットフォームを開きますです。
(2)SIA-TASK:手紙はオープンなインターネットをスケジュールに分散されなければなりません。
第三に、ビジネスシナリオおよび適応の比較利点と欠点を考えます
ビジネス思考:
-
データやアラームの政策を監視豊富なタスク。
-
統一化ログインおよびアクセス制御権限。
- サービス・アクセス・ステップがさらに簡素化。
IV結論
同時実行シナリオに対して特に高いシステム、使いやすいXXL-ジョブ構成の展開、余分な要素を導入する必要がなく、視覚的なコンソールを提供しながら、非常に友好的ではなく、より良い選択です。私たちは、容量のためのオープンソース分散システムフレームワークを直接使用するには、自分の状況に応じて適切な選択を行うことが推奨されていることを願っています。