0

1 日を通して負荷が高いキューがあるとします。キュー内の各メッセージの処理には数秒かかります。

4 台のマシンがすべて外部アクティベーターでセットアップされている場合 (すべて同じキュー/サービス用に構成されている)、それは機能しますか?

機能する場合、ロード バランスをとりますか (作業をワーカー マシン全体に均等に分散しますか)。

4

2 に答える 2

3

これは、最終的には、保留中の複数のWAITFOR (RECEIVE)ステートメントがどのように処理されるかにかかっています。アプリの 4 つのインスタンスが実行されており、それぞれがWAITFOR(RECEIVE). メッセージがキューで使用可能になります。問題は、保留中の WAITFOR(RECEIVE) のどれがメッセージを取得するかということです。

答えは多くの人を驚かせますが、これは設計によるものであり、最後に発行された WAITFOR(RECEIVE) はメッセージを受け取ります。最も古いものでも、ランダムなものでもなく、最新のものです。つまり、リスナーの LIFO 順序です。

なんで?この動作は意図的なものであり、負荷を処理するために必要な数のリスナーを持つことを目的としています。もともと4つのプロセスがリッスンしています。メッセージを取得して処理し、再び を発行することでWAITFOR(RECEIVE)、さらに多くのメッセージをリッスンし始めます。次のメッセージが到着すると、決定論的に同じプロセスに渡されます。これは、最近発行された WAITFOR(RECEIVE) であるためです。このリスナーは、メッセージを取得して処理し、再度 WAITFOR(RECEIVE) を発行します。そして、再び、決定論的に次のメッセージを取得します。要点は次のとおりです。この単一のリスナーがすべての着信トラフィックを処理できる場合、他の 3 つは冗長です。しばらくすると、保留中の WAITFOR(RECEIVE) がタイムアウトになり、これらのプロセスは安全に終了 (終了) します。

2 番目のプロセスは、最初のリスナーが別のメッセージの処理でビジー状態(つまり、新しい WAITFOR(RECEIVE) をポストしていない) の間にメッセージが到着した (使用可能になった) 場合にのみ、メッセージを取得できます。

では、なぜこれが良いのでしょうか?パズルのピースがもう 1 つあります。それは、アクティブ化が発生するタイミングを理解することです。単独の処理スレッドが着信トラフィックを処理できなくなった場合、構成された MAX_QUEUE_READERS まで、新しい処理スレッド (内部または外部) が生成されます。

これで、これら 2 つの動作の間で、自己調整された最適なリーダー (プロセス、スレッド) の数が得られます。

  • トラフィックが急増し、リーダーが少なすぎると、アクティベーション メカニズムによって新しい処理スレッドが生成されます。これは、処理されていないスレッドがキューを「ドレイン」するために 5 秒が経過したときにトリガーされます (RECEIVE は空の行セットを返します)。
  • トラフィックが遅くなり、アクティブ化されたリスナーが多すぎると、トラフィックを処理するために必要な最小限のものが維持され、余剰はタイムアウトになります。
  • トラフィックが一定期間完全に乾燥すると、すべてのスレッド/プロセスがなくなる可能性があります (0 保留中の WAITFOR(RECEIVE))。メッセージが到着すると、それを処理するために処理スレッドがアクティブになります。

相関メッセージ ロック ( Conversation Group Locks ) により、キューにメッセージが含まれる場合がありますが、新しいスレッドで処理できるメッセージがない (つまり、すべてロックされている) ことに注意してください。アクティブ化/待機の目的で、この状況はキューが「空」であることを意味します (新しいプロセッサで使用できるメッセージはありません)。

最後に、これらすべてを実現するには、アプリケーションが正しく動作する必要があります。

  • 通知されたときに新しいスレッドをアクティブ化します (内部アクティベーションはこれを行い、外部アクティベーターも正しく行います)
  • 処理スレッドは、適切なタイムアウトのために WAITFOR(RECEIVE) を発行し、ステートメントがタイムアウトした場合は終了する必要があります (エラーではなく、空の結果セットが返されます)。
  • アクティブ化されたときに RECEIVE を発行することが不可欠です。そうしないと、キュー モニターは NOTIFIED 状態になり、何もアクティブ化されなくなります。キュー モニタについて を参照してください。
于 2013-09-05T07:09:35.823 に答える
1

組み込みの負荷分散を利用するには、サービスを複数の SQL Server インスタンスに展開する必要があります。それはあなたが計画しているものとはかなり違うのではないかと思うので、外部のアクティブ化プロセスが見る 4 つのキューの 1 つに到着したメッセージを転送する内部アクティブ化プロシージャを用意するなど、独自の方法を考え出す必要があります。

于 2013-09-04T14:53:48.327 に答える