序文
アプリケーションの高可用性と高い並行性を確保するために、通常、複数のノードが展開されます。タイミングタスクの場合、各ノードが独自のタイミングタスクを実行する場合、一方でシステムリソースを消費します。
一方、一部のタスクは複数回実行されるため、アプリケーションロジックの問題を引き起こす可能性があるため、タイミングタスクを実行するために各ノードを調整するには分散スケジューリングシステムが必要です。
スプリングはクォーツを統合します
Quartzは成熟したタスクスケジューリングシステムです。 Springは、簡単に開発するためにQuartzと互換性があります。それを統合する方法を見てみましょう:
1.maven依存関係ファイル
<Dependencies> <Dependency> <groupId> org.springframework </groupId> <artifactid> spring-core </artifactid> <version> 4.3.5.Release </version> </dependency> <seplency> <shiplency> <shipalency> <shipaldency </dependency> <dependency> groupid> org.springframework </groupid> <artifactid> spring-tx </artifactid> <version> 4.3.5.release </version> </dependency> <seplency> <ependency> <shipalency> </dependency> <dependency> groupid> org.quartz-scheduler </groupid> <artifactid> quartz </artifactid> <バージョン> 2.2.3 </version> </dependency> <sependency> <shipid> mysql </groupid> <artifactid> mysql-connecton-java </artifactid> </dependency> </dependencies>
主なものは、スプリング関連ライブラリ、Quartzライブラリ、MySQLドライバーライブラリです。注:分散スケジューリングにはデータベースの使用が必要であり、MySQLがここで選択されています。
2。ジョブを構成します
ジョブを構成するには2つの方法があります。
2.1Methodinvokingjobdetailfactorybean
特定の豆の方法を呼び出す場合、特定の構成は次のとおりです。
<bean id = "firstTask"> <プロパティ名= "ターゲットオブジェクト" ref = "firstService" /> <プロパティ名= "ターゲットメトッド" value = "service" /> < /bea>
2.2jobdetailfactorybean
この方法はより柔軟であり、次のように合格パラメーターを設定できます。
<bean id = "firstTask"> <プロパティ名= "jobclass" value = "zh.maven.squartz.task.firsttask"/> <プロパティ名= "jobdatamap"> <map> <entry key = "firstService" first-ref = "firstService"/>> </</財産> </bean> </bean> </bean>
JobClassによって定義されたタスククラスは、Quartzjobbeanを継承し、実行中のメソッドを実装します。 JobDatamapは、データをジョブに渡すために使用されます
3。スケジューリングに使用されるトリガーを構成します
2つのトリガータイプも提供されています:SimpleTriggerFactoryBeanとCrontriggerFactoryBean
CrontriggerFactoryBeanに焦点を当て、次のようにこのタイプはより柔軟です。
<bean id = "firstcrontrigger"> <プロパティ名= "jobdetail" ref = "firsttask" /> <プロパティ名= "cronexpression" value = "0/5 *? * *" /> < /bean>
JobDetailは、ステップ2で構成されたジョブを指定し、Cronexpressionは5秒ごとにジョブを実行するように構成されています。
4. QuartzスケジューラのSchedulerFactoryBeanを構成します
メモリラムジョブストアとデータベースメソッドの2つの方法もあります
4.1メモリラムジョブストア
ジョブ関連の情報はメモリに保存され、各ノードは独自の保存され、互いに分離され、次のように構成されています。
<bean> <プロパティ名= "triggers"> <list> <ref bean = "firstcrontrigger"/> </list> </property> </bean>
4.2データベースメソッド
ジョブの関連情報はデータベースに保存されます。すべてのノードはデータベースを共有します。各ノードは、データベースを介して通信して、ジョブが同時に1つのノードでのみ実行されることを確認します。
ノードが失敗した場合、ジョブは実行のために他のノードに割り当てられます。特定の構成は次のとおりです。
<bean id = "dataSource" Destroy-Method = "close"> <プロパティ名= "driverclass" value = "com.mysql.jdbc.driver" /> <プロパティ名= "jdbcurl" value = "jdbc:mysql:// localhost:3306 /quartz" /> <propertion = "" rut = "" rut = "" rot = "" rot = "propation =" propation = "propation =" propation = "propation </bean> <bean> <プロパティ名= "dataSource" ref = "dataSource"/> <プロパティ名= "configlocation" value = "classpath:quartz.properties"/> <プロパティname = "トリガー"> <リスト
DataSourceは、データソースとデータテーブル関連情報の構成に使用されます。公式WebサイトからGZパッケージをダウンロードできます。 SQLファイルは、主流のデータベースにSQLファイルを提供するパス:docs/dbtablesの下にあります。
Quartz.Properties File configlocationで構成されたファイルは、Quartz.jarのorg.quartzパッケージにあります。
org.quartz.jobstore.class:org.quartz.simpl.ramjobstore
ここでは、Quartz.propertiesをコピーして、いくつかの変更を行う必要があります。特定の変更は次のとおりです。
org.quartz.scheduler.instanceid:autoorg.quartz.jobstore.class:org.quartz.impl.jdbcjobstore.jobstoretxorg.quartz.quartz.jobstore.isclustered:trueorg.quartz.jobstore.clustercheckinval:1000
5。関連カテゴリ
Public Class FirstTaskはQuartzJobbeanを拡張します{private firstService FirstService; @Override Protected void executeInternal(jobexecutioncontextコンテキスト)throws jobexecutionexception {firstService.service(); } public void setFirstService(FirstService FirstService){this.firstService = firstService; }}FirstTaskはQuartzjobbeanを継承し、内部メソッドの実行を実装し、FirstServiceを呼び出します
パブリッククラスFirstServiceはSerializable {private static final long serialversionuid = 1l; public void service(){system.out.println(new simpledateFormat( "yyymmdd hh:mm:ss")。format(new date()) + "--- firstService"); {thread.sleep(2000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println(new simpledateFormat( "yyymmdd hh:mm:ss")。format(new date()) + "--- end firstService"); }}FirstServiceは、データベースに保存する必要があるため、シリアル化インターフェイスを提供する必要があります。
public class app {public static void main(string [] args){abstractApplicationContext context = new ClassPathXMLApplicationContext( "Quartz.xml"); }}メインクラスは、Quartz構成ファイルのロードに使用されます。
テスト分散スケジューリング
1.アプリを同時に2回開始し、ログを観察します。
20180405 14:48:10 --- FirstServiceを開始します
20180405 14:48:12 ---- FirstService
20180405 14:48:15 --- FirstServiceを開始します
20180405 14:48:17 ---- FirstService
その中でも、A1にはログ出力がありますが、A2はログ出力を持っていません。 A1が停止すると、A2にログ出力があります。
2.新しいジョブを追加して、新しいジョブを作成します:それぞれセカンドタスクとセカンドサービス。関連する構成ファイルを同時に追加します。アプリを2回開始し、ログを観察します。
A1ログは次のとおりです。
20180405 15:03:15 --- FirstServiceを開始します
20180405 15:03:15 --- SecondServiceを開始します
20180405 15:03:17 ---- FirstService
20180405 15:03:17 --- sensecservice
20180405 15:03:20 --- FirstServiceを開始します
20180405 15:03:22 ---- FirstService
20180405 15:03:25 --- FirstServiceを開始します
20180405 15:03:27 ---- FirstService
A2ログは次のとおりです。
20180405 15:03:20 --- SecondServiceを開始します
20180405 15:03:22 ---セカンドサービス
20180405 15:03:25 --- SecondServiceを開始します
20180405 15:03:27 ---セカンドサービス
A1とA2の両方が実行タスクを持っていることがわかりますが、同じタスクは同時に1つのノードでのみ実行され、実行が完了した後に他のノードに割り当てることができます。
3.たとえば、間隔時間がタスクの実行時間よりも短い場合、ここでは睡眠に変更されます(6000)
A1ログは次のとおりです。
20180405 15:14:40 --- FirstServiceを開始します
20180405 15:14:45 --- FirstServiceを開始します
20180405 15:14:46 ---- FirstService
20180405 15:14:50 --- FirstServiceを開始します
20180405 15:14:50 --- SecondServiceを開始します
20180405 15:14:51 --- FirstServiceを終了します
A2ログは次のとおりです。
20180405 15:14:40 --- SecondServiceを開始します
20180405 15:14:45 --- SecondServiceを開始します
20180405 15:14:46 ---セカンドサービス
20180405 15:14:51 --- sensecservice
間隔は5秒ですが、タスクの実行には6秒かかります。ログを観察すると、タスクはまだ終わっておらず、新しいタスクが始まっていることがわかります。この状況は、アプリケーションに論理的な問題を引き起こす可能性があります。これは、実際にタスクがシリアルをサポートできるかどうかの問題です。
4。@disallowconcurrentexecutionアノテーションにより、タスクのシリアル化が保証されます
@disallowconcurrentexecution AnnotationをそれぞれFirstTaskとSecondTaskに追加します。ログの結果は次のとおりです。
A1ログは次のとおりです。
20180405 15:32:45 --- FirstServiceを開始します
20180405 15:32:51 --- FirstServiceを終了します
20180405 15:32:51 --- FirstServiceを開始します
20180405 15:32:51 --- SecondServiceを開始します
20180405 15:32:57 ---- FirstService
20180405 15:32:57 ---セカンドサービス
20180405 15:32:57 --- FirstServiceを開始します
20180405 15:32:57 --- SecondServiceを開始します
A2ログは次のとおりです。
20180405 15:32:45 --- SecondServiceを開始します
20180405 15:32:51 --- sensecservice
ログを観察すると、タスクは終了後に新しいタスクを開始し、タスクのシリアル化を実現することがわかります。
要約します
この記事は、スプリング+クォーツ分散スケジューリングを直感的に理解し、実際の使用を通じて問題を解決することを目的としています。もちろん、それがどのようにスケジュールされているか、データベースが吊り下げられた場合など、より深い理解が必要であるなど、多くの質問があるかもしれません。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。