[[378874]] この記事はWeChatの公開アカウント「Java Geek Technology」から転載したもので、著者はYaxue Fansです。この記事を転載する場合は、Java Geek Technology の公開アカウントにお問い合わせください。 1. はじめに 前回の記事では、Quartz のアーキテクチャ原則とアプリケーションの実践について詳細に紹介しました。 Quartz もクラスタリングによってサービスの高可用性を確保できますが、サービスノードの数を増やしてもタスクの実行効率が向上しない、つまり水平拡張が実現できないという欠点もあります。 この結果の理由は、Quartz が分散クラスター環境でデータベース ロックを使用して、サービスを実行する有効なサービス ノードが 1 つだけであることを確認し、クラスター環境内のサービスのスケジュールされたタスクが繰り返し呼び出されないようにするためです。 実行するスケジュールされたタスクが少ない場合は、Quartz を使用しても大きな問題にはなりません。しかし、金融商品など、そのような要件がある場合、システムは毎日6時に各アカウントの昨日の収益を計算する必要があります。この金融商品に何億人ものユーザーがいて、その全員が 1 つのサービス インスタンスで実行されている場合、翌日にはこのタスクを完了できない可能性があります。 同様のシナリオはたくさんあります。明らかに、Quartz では大規模かつ長期サイクルのタスク スケジューリングに対応できません。 そのため、Dangdang.com は、分散環境でのサーバー リソースの効率的な使用に適した、Quartz ベースの Elastic-Job タイミング タスク フレームワークを開発しました。 Elastic-Job-Lite の最大の特徴は、弾性拡張と収縮をサポートしていることです。それはどのように達成されるのでしょうか? 例えば、今実行すべきタスクがある場合、そのタスクを 10 個に分割すると、お互いに影響を与えることなく同時に 10 個のサービス インスタンスで並列実行できるため、タスク実行の効率が大幅に向上し、サーバー リソースを最大限に活用できます。 上記の金融商品の場合、このタスクが 1 億人のユーザーを処理する必要がある場合、水平方向に拡張できます。たとえば、タスクを 500 に分割し、500 のサービス インスタンスを同時に実行し、各サービス インスタンスが 200,000 のデータを処理し、予期しない事態が発生しなければ、すべてを 1 ~ 2 時間で完了できます。それでも時間がかかる場合は、水平方向に拡張を続け、実行するサービス インスタンスを追加できます。 2015年にDangdang.comが一般公開し、瞬く間に多くのプログラマーの注目を集め、中国のオープンソースで第1位にランクされました。 広く使用されているこの分散スケジューリング フレームワークを見てみましょう。 2. プロジェクトアーキテクチャの概要 Elastic-Job にはもともと、軽量で分散化された elastic-job-core という 1 つのプロジェクトしかありませんでした。そのコアサービスは、弾力的な拡張とデータシャーディングをサポートすることでした。 バージョン 2.X 以降では、主に Elastic-Job-Lite と Elastic-Job-Cloud の 2 つのサブプロジェクトに分かれています。 その中でも、Elastic-Job-Lite は軽量の分散ソリューションとして位置付けられており、jar パッケージの形式で分散タスクの調整サービスを提供します。 Elastic-Job-Cloud は Mesos + Docker ソリューションを使用し、リソース管理、アプリケーションの配布、プロセスの分離などの追加サービスを提供します (Lite との唯一の違いはデプロイメント方法です。同じ API を使用し、開発は 1 回だけで済みます)。 本日は主に Elastic-Job-Lite を紹介します。主な機能は次のとおりです。 - 分散スケジューリングと調整: Zookeeper を使用して、統一されたスケジューリングのための登録センターを実装します。
- タスク スライシングをサポート: 実行するタスクをスライシングに分割して、並列スケジューリングを実現します。
- 弾力的な拡張と縮小をサポート: タスクを n 個のタスク項目に分割した後、各サーバーは割り当てられたタスク項目を個別に実行します。新しいサーバーがクラスターに参加するか、既存のサーバーがオフラインになると、elastic-job は現在のタスクの実行を変更せずに、次のタスクが開始する前にタスクの再シャーディングをトリガーします。
もちろん、フェイルオーバーや失敗したジョブ実行の再トリガーなどの機能もあります。より詳しい情報については、公式 Web サイトのドキュメントをご覧ください。 アプリケーションはそれぞれのノード上でタスクを実行し、Zookeeper レジストリを通じて調整されます。ノード登録、ノード選出、タスクシャーディング、監視はすべて E-Job コード内で完了します。下の画像は公式サイトで提供されているアーキテクチャ図です。 では早速、実際にどのようにプレイするのかを理解しやすいように、以下の実践的な紹介を見ていきましょう。 3. 応用演習 3.1、Zookeeperのインストール elastic-job-lite は zookeeper に直接依存しているため、開発前に対応する zookeeper 環境を準備する必要があります。 Zookeeper のインストール プロセスについてはあまり説明しません。非常に簡単で、オンラインでチュートリアルも提供されています。 3.2. elastic-job-lite-consoleのインストール elastic-job-lite-console は主にタスクジョブの視覚化インターフェース管理システムです。 プラットフォームとは関係なく、独立して展開できます。主に登録センターとデータソースを構成することでデータを取得します。 入手方法も非常に簡単です。 https://github.com/apache/shardingsphere-elasticjob に直接アクセスし、バージョン番号 2.1.5 に切り替えてから、mvn clean install を実行してパッケージ化し、対応するインストール パッケージを取得して解凍し、bin フォルダーでサービスを開始します。 インターネットの速度がカタツムリのように遅い場合は、別の方法として、このアドレス https://gitee.com/elasticjob/elastic-job から対応するソース コードを取得します。 サービスを開始したら、ブラウザで http://127.0.0.1:8899 にアクセスし、アカウントとパスワード (両方とも root) を入力して、次のインターフェイスに似たコンソール ページに入ります。 入力後、データベース mysql のデータソースを含め、前述の Zookeeper 登録センターを構成します。 3.3.プロジェクトを作成する この記事では、例として springboot を使用してプロジェクトをビルドし、プロジェクトを作成して elastic-job-lite の依存関係を追加します。 - <!
- <依存関係>
- <groupId>com.dangdang</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <バージョン>2.1.5</バージョン>
- </依存関係>
-
- <!
- <依存関係>
- <groupId>com.dangdang</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
- <バージョン>2.1.5</バージョン>
- </依存関係>
事前に、設定ファイル application.properties で Zookeeper 登録センター関連の情報を設定してください。 - #zookeeper の設定
- 動物園飼育員サーバーリスト=127.0.0.1:2181
- zookeeper.namespace=例-elastic-job-test
3.4.新しいZookeeperConfig構成クラスを作成する - @構成
- @ConditionalOnExpression( "'${zookeeper.serverList}'.length() > 0" )
- パブリッククラスZookeeperConfig {
-
- /**
- * Zookeeperの設定
- * @戻る
- */
- @Bean(initメソッド = "init" )
- パブリックZookeeperRegistryCenter zookeeperRegistryCenter(@Value( "${zookeeper.serverList}" ) 文字列 serverList,
- @Value( "${zookeeper.namespace}" ) 文字列名前空間){
- 新しい ZookeeperRegistryCenter(新しい ZookeeperConfiguration(serverList,namespace))を返します。
- }
-
- }
3.5.新しいタスク処理クラスを作成する Elastic-jobは3種類のジョブタスク処理をサポートします。 - シンプル タイプ ジョブ: シンプル タイプは一般的なタスクを処理するために使用され、SimpleJob インターフェイスのみを実装する必要があります。このインターフェースは、Quartz のネイティブ インターフェースと同様に、定期的に実行されるオーバーライド用の単一のメソッドのみを提供します。
- データフロー型ジョブ: データフロー型はデータ ストリームを処理するために使用され、DataflowJob インターフェイスを実装する必要があります。このインターフェースは、データの取得 (fetchData) と処理 (processData) に使用されるオーバーライド用の 2 つのメソッドを提供します。
- スクリプト タイプのジョブ: スクリプト タイプのジョブとは、シェル、Python、Perl などのすべてのタイプのスクリプトをサポートするスクリプト タイプのジョブを指します。コンソールまたはコードを使用して scriptCommandLine を構成するだけで、コーディングは必要ありません。実行スクリプトのパスにはパラメータを含めることができます。パラメータが渡されると、ジョブ フレームワークは最後のパラメータをジョブ実行時情報として自動的に追加します。
3.6.新しいシンプルタイプのジョブを作成する SimpleJob インターフェースを実装するクラス MySimpleJob を記述します。現在の作業は主にログの印刷です。 - 翻訳者
- パブリッククラスMySimpleJobはSimpleJobを実装します{
-
- @オーバーライド
- パブリックvoid実行(ShardingContext shardingContext) {
- log.info(String.format( "スレッドID: %s、ジョブスライスの合計数: %s、" +
- 「現在のシャードアイテム: %s。現在のパラメータ: %s」 +
- 「ジョブ名: %s。ジョブのカスタム パラメータ: %s」
- 、
- スレッド.currentThread().getId()、
- シャーディングコンテキスト.getShardingTotalCount()、
- シャーディングコンテキスト.getShardingItem()、
- シャーディングコンテキスト.getShardingParameter()、
- シャーディングコンテキスト.getJobName()、
- シャーディングコンテキスト.getJobParameter()
- ));
- }
- }
MySimpleJob タスクの実行を監視するために、MyElasticJobListener タスク リスナーを作成します。 - 翻訳者
- パブリッククラス MyElasticJobListener は ElasticJobListener を実装します {
-
- プライベートlong beginTime = 0;
-
- @オーバーライド
- ジョブが実行される前のパブリックvoid(ShardingContexts shardingContexts) {
- beginTime = System.currentTimeMillis();
- log.info( "===>{} MyElasticJobListener 開始時刻: {} <===" 、shardingContexts.getJobName()、DateFormatUtils.format(new Date ()、 "yyyy-MM-dd HH:mm:ss" ));
- }
-
- @オーバーライド
- ジョブ実行後のパブリックvoid(シャーディングコンテキストshardingContexts) {
- 長い endTime = System.currentTimeMillis();
- log.info( "===>{} MyElasticJobListener 終了時刻: {}、合計キャスト: {} <===" 、shardingContexts.getJobName()、DateFormatUtils.format(new Date ()、 "yyyy-MM-dd HH:mm:ss" )、endTime - beginTime);
- }
-
- }
MySimpleJobConfig クラスを作成し、MySimpleJob を Zookeeper に挿入します。 - @構成
- パブリッククラスMySimpleJobConfig {
-
- /**
- * タスク名
- */
- @Value( "${simpleJob.mySimpleJob.name}" )
- プライベート文字列 mySimpleJobName;
-
- /**
- * Cron式
- */
- @Value( "${simpleJob.mySimpleJob.cron}" )
- プライベート文字列 mySimpleJobCron;
-
- /**
- * ジョブスライスの合計数
- */
- @Value( "${simpleJob.mySimpleJob.shardingTotalCount}" )
- プライベートint mySimpleJobShardingTotalCount;
-
- /**
- * ジョブスライスパラメータ
- */
- @Value( "${simpleJob.mySimpleJob.shardingItemParameters}" )
- プライベート文字列 mySimpleJobShardingItemParameters;
-
- /**
- * カスタムパラメータ
- */
- @Value( "${simpleJob.mySimpleJob.jobParameters}" )
- プライベート文字列 mySimpleJobParameters;
-
- オートワイヤード
- プライベート ZookeeperRegistryCenter registryCenter;
-
- @ビーン
- パブリックMySimpleJob mySimpleJob() {
- 新しいMySimpleJob()を返します。
- }
-
- @Bean(initメソッド = "init" )
- パブリックジョブスケジューラー simpleJobScheduler(final MySimpleJob mySimpleJob) {
- //タスクリスナーを構成する
- MyElasticJobListener の elasticJobListener を新しい MyElasticJobListener() に追加します。
- 新しい SpringJobScheduler(mySimpleJob、registryCenter、getLiteJobConfiguration()、elasticJobListener)を返します。
- }
-
- プライベートLiteJobConfiguration getLiteJobConfiguration() {
- // ジョブのコア構成を定義する
- JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder(mySimpleJobName、mySimpleJobCron、mySimpleJobShardingTotalCount)。
- shardingItemParameters(mySimpleJobShardingItemParameters).jobParameter(mySimpleJobParameters).build();
- // SIMPLE型の設定を定義する
- SimpleJobConfiguration を simpleJobConfig に追加します。
- // Liteジョブのルート構成を定義する
- LiteJobConfiguration の simpleJobRootConfig を LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite( true ).build();
- simpleJobRootConfigを返します。
-
- }
- }
構成ファイル application.properties で対応する mySimpleJob パラメータを構成します。 - #弾性ジョブ
- #simpleJob タイプのジョブ
- simpleJob.mySimpleJob。名前=mySimpleJob
- simpleJob.mySimpleJob.cron=0/15 * * * * ?
- simpleJob.mySimpleJob.shardingTotalCount=3
- simpleJob.mySimpleJob.shardingItemParameters=0=a、1=b、2=c
- simpleJob.mySimpleJob.jobParameters=helloWorld
プログラムを実行して、どのように動作するかを確認します。 上記のデモでは、設定されているシャードの数は 3 です。この時点で、3 つのスレッドが同時にタスクを実行します。これらはすべて 1 台のマシンで実行されるため、このタスクは 3 回実行されます。次に、ポート設定を変更し、3 つの同一のサービス インスタンスを作成します。効果は次のようになります。 タスクが一度実行されたことは一目瞭然です。 3.7.新しいDataFlowJobタイプのジョブを作成する DataFlowJob タイプのタスク構成は SimpleJob に似ており、操作も非常にシンプルです! DataflowJob タイプの実装クラス MyDataFlowJob を作成します。 - 翻訳者
- パブリッククラス MyDataFlowJob は DataflowJob<String> を実装します {
-
- プライベートブールフラグ = false ;
-
- @オーバーライド
- パブリックリスト<String> fetchData(ShardingContext shardingContext) {
- log.info( "データの取得を開始します" );
- if (フラグ) {
- 戻る ヌル;
- }
- Arrays.asList( "qingshan" , "jack" , "seven" )を返します。
- }
-
- @オーバーライド
- パブリックvoid processData(ShardingContext shardingContext、List<String> データ) {
- (文字列値:データ) {
- // データを処理した後は、データを削除する必要があります。削除しないと、実行が継続されます。上記の方法で処理が行えます。ここではフラグを使用します
- log.info( "データの処理を開始します: " + val);
- }
- フラグ = true ;
- }
- }
次に、MyDataFlowJob の構成クラスを作成し、それを Zookeeper レジストリに挿入します。 - 構成
- パブリッククラスMyDataFlowJobConfig {
-
- /**
- * タスク名
- */
- @Value( "${dataflowJob.myDataflowJob.name}" )
- プライベート文字列jobName;
-
- /**
- * Cron式
- */
- @Value( "${dataflowJob.myDataflowJob.cron}" )
- プライベート文字列jobCron;
-
- /**
- * ジョブスライスの合計数
- */
- @Value( "${dataflowJob.myDataflowJob.shardingTotalCount}" )
- プライベートint jobShardingTotalCount;
-
- /**
- * ジョブスライスパラメータ
- */
- @Value( "${dataflowJob.myDataflowJob.shardingItemParameters}" )
- プライベート文字列 jobShardingItemParameters;
-
- /**
- * カスタムパラメータ
- */
- @Value( "${dataflowJob.myDataflowJob.jobParameters}" )
- プライベート文字列jobParameters;
-
- オートワイヤード
- プライベート ZookeeperRegistryCenter registryCenter;
-
-
- @ビーン
- パブリックMyDataFlowJob myDataFlowJob() {
- 新しいMyDataFlowJob()を返します。
- }
-
- @Bean(initメソッド = "init" )
- パブリックジョブスケジューラーデータフロージョブスケジューラー(最終MyDataFlowJob myDataFlowJob) {
- MyElasticJobListener の elasticJobListener を新しい MyElasticJobListener() に追加します。
- 新しい SpringJobScheduler(myDataFlowJob、registryCenter、getLiteJobConfiguration()、elasticJobListener)を返します。
- }
-
- プライベートLiteJobConfiguration getLiteJobConfiguration() {
- // ジョブのコア構成を定義する
- JobCoreConfiguration dataflowCoreConfig = JobCoreConfiguration.newBuilder(jobName、jobCron、jobShardingTotalCount)。
- shardingItemParameters(jobShardingItemParameters).jobParameter(jobParameters).build();
- // DATAFLOW型の構成を定義する
- データフロー ジョブ構成 dataflowJobConfig = 新しいデータフロー ジョブ構成 (dataflowCoreConfig、MyDataFlowJob.class.getCanonicalName()、 false ) ;
- // Liteジョブのルート構成を定義する
- LiteJobConfiguration dataflowJobRootConfig = LiteJobConfiguration.newBuilder(dataflowJobConfig).overwrite( true ).build();
- dataflowJobRootConfigを返します。
-
- }
- }
最後に、構成ファイル application.properties で対応する myDataflowJob パラメータを構成します。 - #データフロー型ジョブ
- データフロージョブ。myDataflowJob。名前=myDataflowJob
- dataflowJob.myDataflowJob.cron=0/15 * * * * ?
- データフロージョブ.myDataflowJob.shardingTotalCount=1
- dataflowJob.myDataflowJob.shardingItemParameters=0=a、1=b、2=c
- dataflowJob.myDataflowJob.jobParameters=myDataflowJobParamter
プログラムを実行して、どのように動作するかを確認します。 ストリーミング処理タイプが設定されている場合は、継続的にデータがプルされ、処理されることに注意してください。プル時に、戻り値が空の場合、データは処理されません。 非ストリーミング処理タイプが設定されている場合、処理は上記の simpleJob タイプと同じになります。 3.8.新しいScriptJobタイプのジョブを作成する ScriptJob タイプのタスク構成は上記と同様です。主にスケジュールされた時間にスクリプトを実行するために使用されます。一般的にはあまり使用されません。 対象がスクリプトなので実行するタスクがないので、タスクジョブ型を記述する必要はありません! ScriptJob タイプの構成クラスを記述するだけで、コマンドは echo 'Hello World! になります。コンテンツ! - @構成
- パブリッククラスMyScriptJobConfig {
-
- /**
- * タスク名
- */
- @Value( "${scriptJob.myScriptJob.name}" )
- プライベート文字列jobName;
-
- /**
- * Cron式
- */
- @Value( "${scriptJob.myScriptJob.cron}" )
- プライベート文字列jobCron;
-
- /**
- * ジョブスライスの合計数
- */
- @Value( "${scriptJob.myScriptJob.shardingTotalCount}" )
- プライベートint jobShardingTotalCount;
-
- /**
- * ジョブスライスパラメータ
- */
- @Value( "${scriptJob.myScriptJob.shardingItemParameters}" )
- プライベート文字列 jobShardingItemParameters;
-
- /**
- * カスタムパラメータ
- */
- @Value( "${scriptJob.myScriptJob.jobParameters}" )
- プライベート文字列jobParameters;
-
- オートワイヤード
- プライベート ZookeeperRegistryCenter registryCenter;
-
-
- @Bean(initメソッド = "init" )
- パブリックジョブスケジューラscriptJobScheduler() {
- MyElasticJobListener の elasticJobListener を新しい MyElasticJobListener() に追加します。
- 新しい JobScheduler(registryCenter、getLiteJobConfiguration()、elasticJobListener)を返します。
- }
-
- プライベートLiteJobConfiguration getLiteJobConfiguration() {
- // ジョブのコア構成を定義する
- JobCoreConfiguration scriptCoreConfig = JobCoreConfiguration.newBuilder(jobName、jobCron、jobShardingTotalCount)。
- shardingItemParameters(jobShardingItemParameters).jobParameter(jobParameters).build();
- // SCRIPT型の設定を定義する
- ScriptJobConfiguration scriptJobConfig = new ScriptJobConfiguration(scriptCoreConfig, "echo 'Hello World!'" );
- // Liteジョブのルート構成を定義する
- LiteJobConfiguration の scriptJobRootConfig を LiteJobConfiguration.newBuilder(scriptJobConfig).overwrite( true ).build();
- scriptJobRootConfigを返します。
-
- }
- }
構成ファイル application.properties で対応する myScriptJob パラメータを構成します。 - #スクリプト型ジョブ
- scriptJob.myScriptJob。名前=myScriptJob
- scriptJob.myScriptJob.cron=0/15 * * * * ?
- scriptJob.myScriptJob.shardingTotalCount=3
- scriptJob.myScriptJob.shardingItemParameters=0=a、1=b、2=c
- scriptJob.myScriptJob.jobParameters=myScriptJobParamter
プログラムを実行して、どのように動作するかを確認します。 3.9.タスクステータスをデータベースに保存する elastic-job がどのようにデータを保存するのか疑問に思う人もいるかもしれません。 ZooInspector クライアントを使用して Zookeeper レジストリに接続すると、対応するタスク構成が対応するツリー ルートに保存されていることがわかります。 特定のタスク実行トラックとステータスの結果は Zookeeper に保存されないため、プロジェクト内のデータ ソースを通じてそれらを永続化する必要があります。 タスクのステータスをデータベースに保存する構成プロセスも非常に簡単です。対応する構成クラスにデータ ソースを挿入するだけで済みます。 MySimpleJobConfig を例にとると、コードは次のようになります。 - @構成
- パブリッククラスMySimpleJobConfig {
-
- /**
- * タスク名
- */
- @Value( "${simpleJob.mySimpleJob.name}" )
- プライベート文字列 mySimpleJobName;
-
- /**
- * Cron式
- */
- @Value( "${simpleJob.mySimpleJob.cron}" )
- プライベート文字列 mySimpleJobCron;
-
- /**
- * ジョブスライスの合計数
- */
- @Value( "${simpleJob.mySimpleJob.shardingTotalCount}" )
- プライベートint mySimpleJobShardingTotalCount;
-
- /**
- * ジョブスライスパラメータ
- */
- @Value( "${simpleJob.mySimpleJob.shardingItemParameters}" )
- プライベート文字列 mySimpleJobShardingItemParameters;
-
- /**
- * カスタムパラメータ
- */
- @Value( "${simpleJob.mySimpleJob.jobParameters}" )
- プライベート文字列 mySimpleJobParameters;
-
- オートワイヤード
- プライベート ZookeeperRegistryCenter registryCenter;
-
- オートワイヤード
- プライベート DataSource dataSource;;
-
-
- @ビーン
- パブリックMySimpleJobストックジョブ() {
- 新しいMySimpleJob()を返します。
- }
-
- @Bean(initメソッド = "init" )
- パブリックジョブスケジューラー simpleJobScheduler(final MySimpleJob mySimpleJob) {
- //イベントデータソース構成を追加する
- ジョブイベント構成 jobEventConfig = 新しい JobEventRdbConfiguration(dataSource);
- MyElasticJobListener の elasticJobListener を新しい MyElasticJobListener() に追加します。
- 新しい SpringJobScheduler(mySimpleJob、registryCenter、getLiteJobConfiguration()、jobEventConfig、elasticJobListener)を返します。
- }
-
- プライベートLiteJobConfiguration getLiteJobConfiguration() {
- // ジョブのコア構成を定義する
- JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder(mySimpleJobName、mySimpleJobCron、mySimpleJobShardingTotalCount)。
- shardingItemParameters(mySimpleJobShardingItemParameters).jobParameter(mySimpleJobParameters).build();
- // SIMPLE型の設定を定義する
- SimpleJobConfiguration を simpleJobConfig に追加します。
- // Liteジョブのルート構成を定義する
- LiteJobConfiguration の simpleJobRootConfig を LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite( true ).build();
- simpleJobRootConfigを返します。
-
- }
- }
同時に、構成ファイル application.properties で対応するデータ ソース パラメータを構成する必要があります。 - spring.datasource.url=jdbc:mysql://127.0.0.1:3306/example-elastic-job-test
- spring.datasource.username=root
- spring.datasource.password =ルート
- spring.datasource.driver-class- name =com.mysql.jdbc.Driver
プログラムを実行し、elastic-job-lite-console コンソールで対応するデータ ソースを構成します。 最後に[ジョブトラック]をクリックすると、該当するジョブの実行ステータスが表示されます。 IV.まとめ この記事では主にelasticjobの使い方を紹介します。そこから何かを学んでいただければ幸いです。 分散環境では、elastic-job-lite は、最大の特徴である弾力的な拡張とタスク シャーディングをサポートします。実際の使用では、タスク シャードの合計数は、シャーディング時にタスクがより均等に分散されるように、できるだけ大きく、サービス インスタンスの数の倍数にする必要があります。 elasticjob についてさらに詳しく知りたい場合は、公式ドキュメントにアクセスして詳細なチュートリアルを参照してください。 5. 参考資料 1. elasticjob - 公式ドキュメント 2. ブログパーク - Wu Zhenzhao - タスクスケジューリングのための Elastic Job |