8

私はそれを知っておりNetwork Load Balancingパッシブサービスを高可用性Failover Clusteringにすることができます。しかし、アクティブなアプリはどうですか?

例:私のアプリの1つが、一定の間隔で外部リソースからコンテンツを取得します。私は次のシナリオを想像しました:

  1. 単一のマシンで実行します。問題:このインスタンスが該当する場合、コンテンツは取得されません
  2. クラスタの各マシンで実行します。問題:コンテンツが複数回取得される
  3. クラスタの各マシンに配置しますが、実行するのはそのうちの1台だけです。各インスタンスは、タスクを実行する順番かどうかを判断するために、ある種の共通リソースをチェックする必要があります。

解決策#3について考えていたとき、私は共通のリソースは何であるべきか疑問に思いました。データベースにテーブルを作成することを考えました。このテーブルを使用して、グローバルロックを取得できます。

これが最善の解決策ですか?人々は通常どのようにこれを行いますか?

ちなみに、これはWindows Server 2008で実行されているC#.NETWCFアプリです。

4

6 に答える 6

4

そのような問題のために、彼らはメッセージキューを発明しました。クラスタ化されたアプリケーションがすべてメッセージキューをリッスンする場合を想像してみてください(それ自体がクラスタ化されています:-))。ある時点で、1つのインスタンスが外部リソースをダウンロードするための最初のコマンドを取得します。成功した場合、インスタンスはメッセージをフラッシュし、代わりに「実行時間」+「間隔」に等しい後の実行時間のために別のメッセージを送信します。ただし、処理中にインスタンスが停止した場合でも、問題はありません。メッセージは(タイムアウト後に)キューにロールバックされ、他のインスタンスがそれを取得できます。少しのトランザクション、少しのメッセージキュー

私は世界のJavaEE側にいるので、コーディングの詳細を手伝うことができます

于 2010-04-20T00:54:09.597 に答える
1

私はかつてあなたのソリューション#3を使用して同様の何かを実装しました。

ロックキーを含むresource_lock列(例)を使用して、のような名前のテーブルを作成します。locking_key

次に、各間隔で、アプリのすべてのインスタンスが次のようになります。

  1. ''のようなクエリを実行しますupdate resource_lock set resource_key = 1 where resource_key is null。(もちろん、サーバー固有のID、タイムスタンプなどを挿入することもできます)
  2. 0行が更新された場合:何もしない-別のアプリインスタンスがすでにリソースをフェッチしています。
  3. 1行が更新された場合:リソースをフェッチして、にlocking_key戻しnullます。

これには2つの利点があります。

  • サーバーの1つに障害が発生した場合でも、リソースはまだ実行中のサーバーによってフェッチされます。
  • ロックはデータベースに任せます。これにより、自分でデータベースを実装する必要がなくなります。
于 2010-04-23T07:34:26.020 に答える
1

単純さの観点から、探していることを達成するための最も迅速で簡単な方法は、クラスターを「ラウンドロビン」して、すべての要求に対してマシンが選択されるようにすることです(クラスター管理サービスなどによって)リクエストを処理します。実際のクライアント要求は、それを処理するマシンに直接送信されません。代わりに、単一のエンドポイントを指します。このエンドポイントは、可用性と負荷に基づいて着信要求をマシンに分散するためのプロキシとして機能します。以下のリンクを引用するには、

ネットワーク負荷分散は、マシンのプールを構成して、マシンが順番に要求に応答するようにする方法です。これは、サーバーファームに実装されるのが最も一般的です。つまり、Webサイトの負荷を分散する同じ構成のマシン、またはターミナルサーバーファームです。ファイアウォール(ISA)ファーム、VPNアクセスポイントにも使用できます。実際には、単一のマシンに対して負荷が高くなりすぎたTCP / IPトラフィックがある場合でも、単一のマシンとして表示する必要があります。アクセス目的。

アプリケーションが「アクティブ」である場合、「アクティブ」か「パッシブ」かに関係なく、アプリケーションはサーバーにリクエストを送信するため、この要件はこの方程式に考慮されません。

HTTPスタイルのリクエストを処理するための商用ロードバランサーが存在するため、検討する価値があるかもしれませんが、W2k8のロードバランシング機能を使用すると、それらを利用するのが最適な場合があります。

Win2k8でそれを構成する方法の詳細については、この記事を参照してください。

この記事ははるかに技術的で、ExchangeでNLBを使用することに焦点を当てていますが、原則は引き続き状況に適用されます。

NLBのセットアップと構成の別の詳細なウォークスルーについては、ここを参照してください。

それができない場合、アプリケーションコードはNLBが存在することさえ厳密に認識していないため、ServerFaultで検索/投稿することで十分に対応できる可能性があります。

編集:別のリンクを追加しました。

編集(2回目):OPは、「アクティブ」と「パッシブ」の概念における私の誤った結論を修正しました。これに対する私の答えは、元の答えと非常に似ていますが、「アクティブな」サービス(WCFを使用しているため、簡単にWindowsサービスになる可能性があります)を実際の処理部分と実際の処理部分の2つの部分に分割できることを除けば管理部分。管理部分は単一のサーバーで実行され、実際の処理を実行する他のサーバーのラウンドロビンロードバランサーとして機能します。元のシナリオよりも少し複雑ですが、かなりの柔軟性があり、処理ロジックと管理ロジックを明確に分離できると思います。

于 2010-04-23T16:34:23.760 に答える
1

あなたがおそらく知っているが、情報に基づいた答えを与えることを困難にする質問で説明されていないいくつかの要件があります。これらの質問のいくつかは次のとおりです。

  • タスクは正常に完了する必要がありますか?
  • タスクが正常に完了する/完了しない場合、「誰が」知る必要があり、どのタイプのアクションを実行する必要がありますか?
  • タスクを再度実行するときにタスクが完了しなかった場合の動作はどうなりますか?実行する必要がありますか?
  • 指定された間隔でジョブを実行することはどれほど重要ですか?間隔が5分ごとの場合、5分ごとにする必要がありますか、それとも5分10秒後にタスクを実行できますか?

最初のステップは、定期的なタスクの実行がどのようにスケジュールされるかを答えることです。1つのオプションはWindowsのスケジュールされたタスクですが、それは本質的に高可用性ではありませんが、それを回避できる可能性があります。SQL Serverを使用している場合、SQL Serverの一部としてフェールオーバーするため、SQLServerエージェントをスケジューラーとして使用することもできます。

決定する次のステップは、WCFアプリケーションを呼び出す方法です。最も簡単なオプションは、ジョブをトリガーして、NLBIPアドレスを介してWCFサービスを呼び出すことです。データベースサーバー(またはそのゾーン内の他のサーバー)がアプリケーションゾーンを呼び出している場合、これはノーノーと見なすことができます(もちろん、MSDTCなどの例外は常にあります)。

別のオプションは、キューモデルを使用することです。これは、ほとんどの状況で最も信頼性が高くなります。たとえば、SQL Serverエージェントは、ストアドプロシージャを実行して、キューテーブルにレコードを入力できます。次に、各アプリケーションサーバーで、サービスは処理するキューに入れられたレコードを探してポーリングできます。キュー内のレコードへのアクセスはデータベースによってシリアル化されるため、の最初のサーバーがジョブを実行します(そのジョブは1回だけ実行されます)。

この回答の最初の質問に対する回答によっては、エラー処理をさらに追加する必要がある場合があります。外部リソースの取得が通常かなり短い場合は、キューレコードをでロックしたままselect for updateにし、タスクが完了したらステータスを更新します(または必要に応じてレコードを削除します)。これにより、別のサーバーで処理されている間、他のサービスインスタンスがレコードを処理できなくなります。処理中にクラッシュが発生した場合は、トランザクションをロールバックする必要があり、クラスター内の別のサービスがレコードを取得できます。(ただし、必要と思われる限り、トランザクションのタイムアウトを増やすことができます。)

データベースロックを長期間維持できない場合は、ロジックを変更して、サービスに監視を追加することができます。これで、ジョブの処理が開始されると、そのステータスがキューから実行中に変更され、レコードを処理しているサーバーがレコードで更新されます。ある種のサービスステータステーブルを作成すると、各サービスインスタンスは、ポーリングするたびに現在の時刻を更新します。これにより、クラスター内の他のサービスが、実行中であると表示されているジョブを再処理できるようになりますが、実行されているはずのサービスが特定の期間内に「チェックイン」されていません。

このアプローチにも制限があります。タスクが実際に完了したが、何らかの理由でデータベース接続が失われた場合、ジョブが再度実行される可能性があります。もちろん、アトミックデータベースアクションを他の非トランザクションリソース(Webリクエスト、ファイルシステムなど)と組み合わせるという問題は簡単には解決されないと思います。私はあなたがファイルか何かを書いていると仮定しています-外部コンテンツもデータベースに配置されている場合、単一のトランザクションはすべてが一貫していることを保証します。

于 2010-04-26T05:53:13.427 に答える
0

場合によっては、3台のマシンですべての要求を実行し、最後に結果を比較して、結果が完全に正しく、ハードウェア障害が処理中に問題を引き起こしていないことを確認すると便利な場合があります。これは彼らが例えば飛行機で行うことです。

また、悪い結果が1つあり、新しいサービスに切り替えるためのダウンタイムが短い場合でも、次のサービスに問題がないことを望んでいる場合もあります。その場合、心拍数モニターを備えたソリューション番号3は優れたセットアップです。

また、SMSでサービスがダウンしていることを通知するだけで、手動で何らかのフェイルオーバーを実行するまで、アプリケーションは古いデータを使用することもあります。

あなたの場合、後者の方がおそらくあなたにとってより有用だと思います。相手側のサービスが利用可能であることに本当に依存することはできないので、その場合に何をすべきかについての解決策を考え出す必要があります。廃止されたデータを返すことはあなたにとって良いことかもしれませんし、そうでないかもしれません。申し訳ありませんが、それは状況によって異なります。

于 2010-04-22T09:34:18.410 に答える
0

Zookeeperは、分散ロックの優れたユースケースです。Zookeeperには、データを含むディレクトリのようなzノードがあります。

netflixのキュレーターでさえ、すでに多くのレシピが作成されており、使用することができます。のように:リーダー選出、分散ロックなど。

C#の飼育係のクライアントがいると思います。あなたは間違いなくこのオプションを試してみるべきです。#Option3

于 2013-07-30T06:51:55.107 に答える