あなたがおそらく知っているが、情報に基づいた答えを与えることを困難にする質問で説明されていないいくつかの要件があります。これらの質問のいくつかは次のとおりです。
- タスクは正常に完了する必要がありますか?
- タスクが正常に完了する/完了しない場合、「誰が」知る必要があり、どのタイプのアクションを実行する必要がありますか?
- タスクを再度実行するときにタスクが完了しなかった場合の動作はどうなりますか?実行する必要がありますか?
- 指定された間隔でジョブを実行することはどれほど重要ですか?間隔が5分ごとの場合、5分ごとにする必要がありますか、それとも5分10秒後にタスクを実行できますか?
最初のステップは、定期的なタスクの実行がどのようにスケジュールされるかを答えることです。1つのオプションはWindowsのスケジュールされたタスクですが、それは本質的に高可用性ではありませんが、それを回避できる可能性があります。SQL Serverを使用している場合、SQL Serverの一部としてフェールオーバーするため、SQLServerエージェントをスケジューラーとして使用することもできます。
決定する次のステップは、WCFアプリケーションを呼び出す方法です。最も簡単なオプションは、ジョブをトリガーして、NLBIPアドレスを介してWCFサービスを呼び出すことです。データベースサーバー(またはそのゾーン内の他のサーバー)がアプリケーションゾーンを呼び出している場合、これはノーノーと見なすことができます(もちろん、MSDTCなどの例外は常にあります)。
別のオプションは、キューモデルを使用することです。これは、ほとんどの状況で最も信頼性が高くなります。たとえば、SQL Serverエージェントは、ストアドプロシージャを実行して、キューテーブルにレコードを入力できます。次に、各アプリケーションサーバーで、サービスは処理するキューに入れられたレコードを探してポーリングできます。キュー内のレコードへのアクセスはデータベースによってシリアル化されるため、の最初のサーバーがジョブを実行します(そのジョブは1回だけ実行されます)。
この回答の最初の質問に対する回答によっては、エラー処理をさらに追加する必要がある場合があります。外部リソースの取得が通常かなり短い場合は、キューレコードをでロックしたままselect for update
にし、タスクが完了したらステータスを更新します(または必要に応じてレコードを削除します)。これにより、別のサーバーで処理されている間、他のサービスインスタンスがレコードを処理できなくなります。処理中にクラッシュが発生した場合は、トランザクションをロールバックする必要があり、クラスター内の別のサービスがレコードを取得できます。(ただし、必要と思われる限り、トランザクションのタイムアウトを増やすことができます。)
データベースロックを長期間維持できない場合は、ロジックを変更して、サービスに監視を追加することができます。これで、ジョブの処理が開始されると、そのステータスがキューから実行中に変更され、レコードを処理しているサーバーがレコードで更新されます。ある種のサービスステータステーブルを作成すると、各サービスインスタンスは、ポーリングするたびに現在の時刻を更新します。これにより、クラスター内の他のサービスが、実行中であると表示されているジョブを再処理できるようになりますが、実行されているはずのサービスが特定の期間内に「チェックイン」されていません。
このアプローチにも制限があります。タスクが実際に完了したが、何らかの理由でデータベース接続が失われた場合、ジョブが再度実行される可能性があります。もちろん、アトミックデータベースアクションを他の非トランザクションリソース(Webリクエスト、ファイルシステムなど)と組み合わせるという問題は簡単には解決されないと思います。私はあなたがファイルか何かを書いていると仮定しています-外部コンテンツもデータベースに配置されている場合、単一のトランザクションはすべてが一貫していることを保証します。