Scheduler実装サービス jp.ossc.nimbus.service.scheduler2.DefaultSchedulerService

jp.ossc.nimbus.service.scheduler2.DefaultSchedulerServiceは、スケジュールをQueueを使って非同期処理するScheduler実装サービスです。

このサービスは、実行すべきスケジュールを監視するスレッドを1つ持ちます。
監視スレッドは、定期的にスケジュールを管理するScheduleManagerに「現在実行すべきスケジュール」を問い合わせます。
「現在実行すべきスケジュール」が存在する場合、スケジュールを取得して、Queueにスケジュールを投入します。その際、ScheduleManagerに依頼して、スケジュールの状態を「投入」に変更します。
また、このサービスは、内部にQueueHandlerContainerを持ちQueueに投入されたスケジュールを受けとる処理スレッドをプールしています。
処理スレッドは、Queueからスケジュールを受け取ると、ScheduleExecutorにスケジュールの実行を依頼します。その際、ScheduleManagerに依頼して、スケジュールの状態を「実行中」に変更します。
その後、ScheduleExecutorの応答に応じて、ScheduleManagerに依頼してスケジュールの状態を「正常終了」、「異常終了」、「中断」、「リトライ」などに変更します。

スケジューラのクラスタ化は、Active-Active構成とActive-Standby構成の2パターンあります。
クラスタ化する場合、前提として、ScheduleManagerの実装サービスが、サーバを跨いでもスケジュールを共有できる実装である必要があります。

Active-Active構成の場合は、それぞれのサーバ上のスケジューラは、互いの存在を意識する事なく動作します。
そのため、利点としては、分散設計が単純である(フェイルオーバがない)ことです。
逆に欠点は、サーバ間でスケジュールの処理割り当ての調整を行わないため、ロードバランスとしては、適切には行われません。取ったもの勝ちで処理していきます。但し、属性ExecutorKeyでスケジューラに論理的な名前を与える事が可能で、スケジュール毎に処理するスケジューラを指定する事で、静的にロードバランスを決める事はできます。

Active-Standby構成の場合は、スケジューラは、どこか1台のサーバのみが稼働します。但し、待機系のサーバは、純粋に待機している訳ではなく、スケジュールを実行するScheduleExecutorは稼働します。つまり、スケジュールを監視して投入するサーバは1台ですが、実行は全サーバのどこかにロードバランスして、実行することで、負荷分散を行います。
そのため、利点としては、各サーバの負荷に応じてロードバランスを行う事ができ、リソースを有効に活用できる事です。もちろん、Active-Active構成の時と同様に、スケジュール毎に静的なロードバランスを指定する事もできます。但し、待機系のスケジューラは稼働しないため、スケジュール割り当てのための論理名は、ScheduleExecutorの属性ExecutorKeyで設定します。
逆に、欠点としては、分散設計が複雑である(フェイルオーバがあり、稼働系と待機系で異なる挙動をしている)ことです。
ロードバランスのポリシーは、jp.ossc.nimbus.service.keepalive.KeepAliveCheckerSelectorサービスの実装クラスに依存します。

このサービスは、複合的なサービスで、以下のサービスを下位サービスとして使用します。

下位サービスインタフェース用途
jp.ossc.nimbus.service.scheduler2.ScheduleManager実行すべきスケジュールを取得する。
jp.ossc.nimbus.service.scheduler2.ScheduleExecutorスケジュールの実行を依頼する。
jp.ossc.nimbus.service.keepalive.ClusterServiceスケジューラをクラスタ化する。
jp.ossc.nimbus.service.sequence.Sequenceスケジュールの処理通番を発行する。
jp.ossc.nimbus.service.context.ThreadContextServiceスケジュールの処理通番を設定する。
jp.ossc.nimbus.service.transaction.TransactionManagerFactoryjavax.transaction.TransactionManagerを取得する
jp.ossc.nimbus.service.queue.Queueスケジュールの実行を非同期に行うためのキュー。

以下に簡単なサービス定義を示します。

  1. <?xml version="1.0" encoding="Shift_JIS"?>
  2. <!DOCTYPE server PUBLIC
  3. "-//Nimbus//DTD Nimbus 1.0//JA"
  4. "http://nimbus.sourceforge.jp/dtd/nimbus-service_1_0.dtd">
  5. <server>
  6. <manager>
  7. <!-- スケジューラサービス -->
  8. <service name="Scheduler"
  9. code="jp.ossc.nimbus.service.scheduler2.DefaultSchedulerService">
  10. <!-- ScheduleManagerサービスのサービス名を設定する -->
  11. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  12. <!-- ScheduleExecuterサービスのサービス名を設定する -->
  13. <attribute name="ScheduleExecutorServiceName">#ScheduleExecutor</attribute>
  14. <!-- スケジュール実行スレッド数を設定する -->
  15. <attribute name="ScheduleDispatcherSize">5</attribute>
  16. <depends>ScheduleManager</depends>
  17. <depends>ScheduleExecutor</depends>
  18. </service>
  19. <!-- ScheduleManagerサービス -->
  20. <service name="ScheduleManager"
  21. code="jp.ossc.nimbus.service.scheduler2.DefaultScheduleManagerService">
  22. <attribute name="ScheduleMasterServiceNames">
  23. #ScheduleMaster1
  24. #ScheduleMaster2
  25. #ScheduleMaster3
  26. #ScheduleMaster4
  27. </attribute>
  28. <attribute name="PersistDir">./schedule</attribute>
  29. <depends>
  30. <!-- スケジュールマスタ1
  31. 08:00:00にFlow1を実行するスケジュール
  32. -->
  33. <service name="ScheduleMaster1"
  34. code="jp.ossc.nimbus.service.scheduler2.DefaultScheduleMaster">
  35. <attribute name="Id">Schedule1</attribute>
  36. <attribute name="TaskName">Flow1</attribute>
  37. <attribute name="StartTime">// 08:00:00 000</attribute>
  38. </service>
  39. </depends>
  40. <depends>
  41. <!-- スケジュールマスタ2
  42. スケジュールマスタ1の終了を待って、08:00:00にFlow2を実行するスケジュール
  43. -->
  44. <service name="ScheduleMaster2"
  45. code="jp.ossc.nimbus.service.scheduler2.DefaultScheduleMaster">
  46. <attribute name="Id">Schedule2</attribute>
  47. <attribute name="TaskName">Flow2</attribute>
  48. <attribute name="StartTime">// 08:00:00 000</attribute>
  49. <attribute name="Input">100</attribute>
  50. <attribute name="Depends">Schedule1</attribute>
  51. </service>
  52. </depends>
  53. <depends>
  54. <!-- スケジュールマスタ3
  55. スケジュールマスタ2の終了を待って、08:01:00から08:02:00まで5秒間隔にFlow3を実行するスケジュール
  56. -->
  57. <service name="ScheduleMaster3"
  58. code="jp.ossc.nimbus.service.scheduler2.DefaultScheduleMaster">
  59. <attribute name="Id">Schedule3</attribute>
  60. <attribute name="TaskName">Flow3</attribute>
  61. <attribute name="StartTime">// 08:01:00 000</attribute>
  62. <attribute name="EndTime">// 08:02:00 000</attribute>
  63. <attribute name="RepeatInterval">5000</attribute>
  64. <attribute name="Depends">Schedule2</attribute>
  65. </service>
  66. </depends>
  67. <depends>
  68. <!-- スケジュールマスタ4
  69. スケジュールマスタ1とスケジュールマスタ3の終了を待って、08:00:00から08:03:00までFlow4の結果でリトライを指示される限り、10秒間隔でFlow4を実行するスケジュール
  70. 08:03:00に達しても、リトライを指示された場合は、エラー終了する
  71. -->
  72. <service name="ScheduleMaster4"
  73. code="jp.ossc.nimbus.service.scheduler2.DefaultScheduleMaster">
  74. <attribute name="Id">Schedule4</attribute>
  75. <attribute name="TaskName">Flow4</attribute>
  76. <attribute name="StartTime">// 08:00:00 000</attribute>
  77. <attribute name="Depends">Schedule1,Schedule3</attribute>
  78. <attribute name="RetryInterval">10000</attribute>
  79. <attribute name="RetryEndTime">// 08:03:00 000</attribute>
  80. </service>
  81. </depends>
  82. </service>
  83. <!-- ScheduleExecuterサービス -->
  84. <service name="ScheduleExecutor"
  85. code="jp.ossc.nimbus.service.scheduler2.BeanFlowScheduleExecutorService">
  86. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  87. <attribute name="BeanFlowInvokerFactoryServiceName">#BeanFlowInvokerFactory</attribute>
  88. <depends>ScheduleManager</depends>
  89. <depends>BeanFlowInvokerFactory</depends>
  90. </service>
  91. <!-- BeanFlowInvokerを生成するBeanFlowInvokerFactoryサービス -->
  92. <service name="BeanFlowInvokerFactory"
  93. code="jp.ossc.nimbus.service.beancontrol.DefaultBeanFlowInvokerFactoryService">
  94. <attribute name="DirPaths">flows</attribute>
  95. <attribute name="BeanFlowInvokerAccessClass">jp.ossc.nimbus.service.beancontrol.BeanFlowInvokerAccessImpl2</attribute>
  96. <attribute name="Validate">true</attribute>
  97. </service>
  98. </manager>
  99. </server>

以下に、クラスタ構成でActive-Active構成の場合の、サービス定義を示します。

  1. <?xml version="1.0" encoding="Shift_JIS"?>
  2. <!DOCTYPE server PUBLIC
  3. "-//Nimbus//DTD Nimbus 1.0//JA"
  4. "http://nimbus.sourceforge.jp/dtd/nimbus-service_1_0.dtd">
  5. <server>
  6. <manager>
  7. <!-- スケジューラサービス -->
  8. <service name="Scheduler"
  9. code="jp.ossc.nimbus.service.scheduler2.DefaultSchedulerService">
  10. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  11. <attribute name="ScheduleExecutorServiceName">#ScheduleExecutor</attribute>
  12. <attribute name="ScheduleDispatcherSize">5</attribute>
  13. <!-- 実行キーを設定する -->
  14. <attribute name="ExecutorKey">
  15. <invoke name="getHostName"><target><static-invoke code="java.net.InetAddress" name="getLocalHost"/></target></invoke>
  16. </attribute>
  17. <depends>ScheduleManager</depends>
  18. <depends>ScheduleExecutor</depends>
  19. </service>
  20. <!-- ScheduleManagerサービス -->
  21. <service name="ScheduleManager"
  22. code="jp.ossc.nimbus.service.scheduler2.DatabaseScheduleManagerService">
  23. <attribute name="ConnectionFactoryServiceName">#ConnectionFactory</attribute>
  24. <attribute name="SequenceServiceName">#Sequence</attribute>
  25. <!-- 実行可能スケジュールを検索する際にレコードをロックするかどうかを設定する -->
  26. <attribute name="LockForFindExecutable">true</attribute>
  27. <depends>ConnectionFactory</depends>
  28. <depends>Sequence</depends>
  29. </service>
  30. <!-- JDBCドライバ経由でConnectionを取得するConnectionFactoryサービス -->
  31. <service name="ConnectionFactory"
  32. code="jp.ossc.nimbus.service.connection.JDBCConnectionFactoryService">
  33. <attribute name="DriverName">oracle.jdbc.driver.OracleDriver</attribute>
  34. <attribute name="ConnectionURL">jdbc:oracle:thin:@192.174.1.11:1521:SAMPLE</attribute>
  35. <attribute name="UserName">hgoe</attribute>
  36. <attribute name="Password">fuga</attribute>
  37. </service>
  38. <!-- 通番を発行するSequenceサービス -->
  39. <service name="Sequence"
  40. code="jp.ossc.nimbus.service.sequence.StringSequenceService">
  41. <attribute name="Format">TIME_SEQ(yyyyMMdd,5)</attribute>
  42. </service>
  43. <!-- ScheduleExecuterサービス -->
  44. <service name="ScheduleExecutor"
  45. code="jp.ossc.nimbus.service.scheduler2.BeanFlowScheduleExecutorService">
  46. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  47. <attribute name="BeanFlowInvokerFactoryServiceName">#BeanFlowInvokerFactory</attribute>
  48. <depends>ScheduleManager</depends>
  49. <depends>BeanFlowInvokerFactory</depends>
  50. </service>
  51. <!-- BeanFlowInvokerを生成するBeanFlowInvokerFactoryサービス -->
  52. <service name="BeanFlowInvokerFactory"
  53. code="jp.ossc.nimbus.service.beancontrol.DefaultBeanFlowInvokerFactoryService">
  54. <attribute name="DirPaths">flows</attribute>
  55. <attribute name="BeanFlowInvokerAccessClass">jp.ossc.nimbus.service.beancontrol.BeanFlowInvokerAccessImpl2</attribute>
  56. <attribute name="Validate">true</attribute>
  57. </service>
  58. </manager>
  59. </server>

以下に、クラスタ構成でActive-Standby構成の場合の、サービス定義を示します。

  1. <?xml version="1.0" encoding="Shift_JIS"?>
  2. <!DOCTYPE server PUBLIC
  3. "-//Nimbus//DTD Nimbus 1.0//JA"
  4. "http://nimbus.sourceforge.jp/dtd/nimbus-service_1_0.dtd">
  5. <server>
  6. <manager>
  7. <!-- スケジューラサービス -->
  8. <service name="Scheduler"
  9. code="jp.ossc.nimbus.service.scheduler2.DefaultSchedulerService">
  10. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  11. <attribute name="ScheduleExecutorServiceName">#ScheduleExecutor</attribute>
  12. <attribute name="ScheduleDispatcherSize">5</attribute>
  13. <!-- クラスタサービスのサービス名を設定する -->
  14. <attribute name="ClusterServiceName">#Cluster</attribute>
  15. <depends>ScheduleManager</depends>
  16. <depends>ScheduleExecutor</depends>
  17. <depends>Cluster</depends>
  18. </service>
  19. <!-- ScheduleManagerサービス -->
  20. <service name="ScheduleManager"
  21. code="jp.ossc.nimbus.service.scheduler2.DatabaseScheduleManagerService">
  22. <attribute name="ConnectionFactoryServiceName">#ConnectionFactory</attribute>
  23. <attribute name="SequenceServiceName">#Sequence</attribute>
  24. <!-- クラスタサービスのサービス名を設定する -->
  25. <attribute name="ClusterServiceName">#Cluster</attribute>
  26. <depends>ConnectionFactory</depends>
  27. <depends>Sequence</depends>
  28. <depends>Cluster</depends>
  29. </service>
  30. <!-- JDBCドライバ経由でConnectionを取得するConnectionFactoryサービス -->
  31. <service name="ConnectionFactory"
  32. code="jp.ossc.nimbus.service.connection.JDBCConnectionFactoryService">
  33. <attribute name="DriverName">oracle.jdbc.driver.OracleDriver</attribute>
  34. <attribute name="ConnectionURL">jdbc:oracle:thin:@192.174.1.11:1521:SAMPLE</attribute>
  35. <attribute name="UserName">hgoe</attribute>
  36. <attribute name="Password">fuga</attribute>
  37. </service>
  38. <!-- 通番を発行するSequenceサービス -->
  39. <service name="Sequence"
  40. code="jp.ossc.nimbus.service.sequence.StringSequenceService">
  41. <attribute name="Format">TIME_SEQ(yyyyMMdd,5)</attribute>
  42. </service>
  43. <!-- クラスタ化されたScheduleExecuterを呼び出すプロキシサービス -->
  44. <service name="ScheduleExecutor"
  45. code="jp.ossc.nimbus.service.proxy.RemoteClientService">
  46. <attribute name="RemoteInterfaceClassName">jp.ossc.nimbus.service.scheduler2.ScheduleExecutor</attribute>
  47. <attribute name="InvokerServiceName">#ClusterInvoker</attribute>
  48. <depends>ClusterInvoker</depends>
  49. <depends>LocalScheduleExecutor</depends>
  50. </service>
  51. <!-- クラスタ呼び出しサービス -->
  52. <service name="ClusterInvoker"
  53. code="jp.ossc.nimbus.service.scheduler2.ScheduleExecutorClusterInvokerService">
  54. <attribute name="KeepAliveCheckerSelectorServiceName">#KeepAliveCheckerSelector</attribute>
  55. <depends>KeepAliveCheckerSelector</depends>
  56. </service>
  57. <!-- 生存監視サービス -->
  58. <service name="KeepAliveCheckerSelector"
  59. code="jp.ossc.nimbus.service.keepalive.RoundRobinKeepAliveCheckerSelectorService">
  60. <attribute name="ClusterServiceName">#Cluster</attribute>
  61. <depends>Cluster</depends>
  62. </service>
  63. <!-- クラスタサービス -->
  64. <service name="Cluster"
  65. code="jp.ossc.nimbus.service.keepalive.ClusterService">
  66. <attribute name="LocalAddress">0.0.0.0</attribute>
  67. <attribute name="MulticastGroupAddress">239.0.0.10</attribute>
  68. <attribute name="HeartBeatRetryCount">2</attribute>
  69. <attribute name="JoinOnStart">false</attribute>
  70. </service>
  71. <!-- ローカルのScheduleExecuterサービス -->
  72. <service name="LocalScheduleExecutor"
  73. code="jp.ossc.nimbus.service.scheduler2.BeanFlowScheduleExecutorService">
  74. <attribute name="ScheduleManagerServiceName">#ScheduleManager</attribute>
  75. <attribute name="BeanFlowInvokerFactoryServiceName">#BeanFlowInvokerFactory</attribute>
  76. <!-- 実行キーを設定する -->
  77. <attribute name="ExecutorKey">
  78. <invoke name="getHostName"><target><static-invoke code="java.net.InetAddress" name="getLocalHost"/></target></invoke>
  79. </attribute>
  80. <depends>ScheduleManager</depends>
  81. <depends>BeanFlowInvokerFactory</depends>
  82. </service>
  83. <!-- BeanFlowInvokerを生成するBeanFlowInvokerFactoryサービス -->
  84. <service name="BeanFlowInvokerFactory"
  85. code="jp.ossc.nimbus.service.beancontrol.DefaultBeanFlowInvokerFactoryService">
  86. <attribute name="DirPaths">flows</attribute>
  87. <attribute name="BeanFlowInvokerAccessClass">jp.ossc.nimbus.service.beancontrol.BeanFlowInvokerAccessImpl2</attribute>
  88. <attribute name="Validate">true</attribute>
  89. </service>
  90. </manager>
  91. </server>


スケジューラ/高機能スケジューラ/Scheduler