3

私はそれぞれ3つのwcfサービスA、B、Cを持っています。これは、SOA(Service Oriented Architecture)にしたかったので、セットアップが機能する方法は、クライアントからサーバーに要求を送信するときです。

  1. すべてのサービスは、自己ホスト型のWindowsサービスです。
  2. クライアントはサービスAにリクエストを送信します(クライアントは他のサービスBとCについての手がかりを持っていません)。
  3. サービスAは、最終的にその要求をサービスBとサービスCに送信します。
  4. サービスBとCは応答をサービスAに送り返し、サービスAはサービスAによってクライアントに送り返されます。

直面している問題:サービスBのコードに変更を加えてサービスを再構築して再起動すると、応答を取り戻すのに問題がありますが、残りのすべてのサービスを再起動すると正常に動作します。

つまり、1つのサービスだけでコードを変更して再構築しただけなのに、すべてのサービス(A、B、C)を再起動しない限り、クライアントは応答を返しません。 3つのサービスですが、これが私の設計上の問題なのか、それともセルフホストのWindowsサービスを処理する必要があるのか​​を知りたいのですが、すべてのサービス(A、B、C)は相互に依存していないため、独立しています。

誰かがSOAでそのようなことが起こったのを見たことがありますか?誰かが私を適切な解決策に導くことができれば嬉しいですか?

4

2 に答える 2

3
  1. サービス間のWCFを任意の種類のキューに置き換えます(1つのサービスは何かを公​​開し、他のサービスは準備ができたときに読み取ることができます)。何でもかまいません。何か新しいことがあれば、そこから読み取る単純なテーブルにすることができます。RabbitMQ、NServiceBusなど、自分に合ったものなら何でもかまいません。

  2. キューに入れるメッセージを定義します:コマンドとイベント。どちらもプロパティを持つ単純なクラスであり、ロジックはありません。コマンドはシステムに要求されること(RegisterUser、PlaceOrderなど)を表し、イベントはシステムが実行したこと(UserRegistered、OrderApproved、PaymentReceivedなど)を表します。アクションについて明示的にしてください。「クライアント上のユーザーのすべてのプロパティを変更しました。今度はSaveUser(user)を呼び出します」のようなことはしないでください。あなたのサービスはオブジェクトを変更する方法を知っていると想定しています、クライアントはをすべきかを命令するだけです。

  3. 契約を破らないでください。思ったより簡単です。メッセージコントラクトに追加することはできますが、削除することはできません。つまり、コントラクトの下位互換性を維持するだけです。

これで、はるかに優れた設計が可能になりました。サービスはキュー内のメッセージを介してのみ通信し、メッセージには下位互換性があります。つまり、他のサービスに影響を与えることなく、いつでもサービスを停止できます。サービスは引き続きメッセージをキューに送信し、停止したサービスが再び戻ってくると、キューからのすべてのものの処理に追いつきます。

次に、必要に応じて、クライアントとのやり取りで同じアプローチを使用できます。WCFを呼び出す代わりに、クライアントがコマンドをある種のキューに入れるだけの場合、サービスのアップグレードやその他のダウンタイムはユーザーエクスペリエンスに影響を与えません。

例:WCFを使用して注文したり、ショッピングカードに商品を入れたりした場合、問題が発生したり、メンテナンスのためにサービスが停止したりすると、それを行うことができなくなります。ボタンをクリックすると、厄介なエラーが発生します。さらに重要なことに、私の注文はシステムに組み込まれません。対照的に、途中にキューがある場合は、コマンドをキューに入れるだけです。これで、サービスが現在ダウンしている場合や、負荷が高い(したがって遅い)場合でも、ユーザーエクスペリエンスは同じであり、低下することはありません。コマンドが少し後で処理されるだけですが、クライアントとしてはあまり気にしません。そして、私の注文はこのシナリオで失われることはありません。システムは、障害に耐え、自己バランスが取れるようになりました。

WCFに付属する空間的および時間的結合の問題を経験するのではなく、単にキューを中央に配置するだけで実行できるさまざまな素晴らしいトリックがあります:)そして私が説明したのはほんの始まりにすぎません... :)

于 2013-02-22T13:31:36.217 に答える
1

機能を実現するために、 NServiceBusなどのサービスバスの使用を検討することをお勧めします。

対処に役立つ最初の問題は、パブリッシュ/サブスクライブメッセージングパターンを介したサービスの分離です。いずれかのサービスでWebサービスを呼び出すのではなく、何かが発生したときにそれぞれのサービスに通知するイベントを公開します。あなたの場合、これは次のようになります。

  1. クライアントはサービスAでWebサービスを呼び出します。
  2. サービスAは、サービスBとCがサブスクライブするメッセージ「ClientCommandReceived」を発行します。
  3. サービスBとCはこのイベントを処理してから、独自のイベントを公開します。
  4. サービスAは、イベントとクライアントへの応答の両方をサブスクライブします。

NServiceBusを使用することの最初の直接的な利点は、信頼性です。さらに、クライアントやそれぞれのサービスに影響を与えることなく、メッセージを簡単にバージョン管理できます。NServiceBusには完全なWCF統合があるため、クライアントは以前と同じようにサービスにメッセージを送信し続けることができます。

シナリオを面白くすることの1つは、サービスBとCがいつ応答を返送するかを保証できないことです。サービスが応答を受信するまで、クライアントへの接続を開いたままにしますか?クライアントに応答を送信する前に、両方の応答が必要ですか?サービスのいずれかまたは1つがクラッシュした場合はどうなりますか?サービスAが応答を受信するまでの待機時間に制限がある場合はどうなりますか?これらすべての質問およびその他の質問には、Sagasと呼ばれるNServiceBusの機能を使用して回答できます。見てみな。

NServiceBusを使用できない場合は、事態はさらに困難になります。WCFは、すぐに使用できるパブリッシュ/サブスクライブをサポートしていないため、独自に作成する必要があります。少なくとも、これを使用してサービスを分離することをお勧めします。サービスの状態と時間の結合をどのように管理するかは別の問題です。手間を省きましょう。

他にもフレームワークがありますが、開発者中心の費用効果の高い方法で.NETベースのソリューションを作成する場合は、NServiceBusの使用をお勧めします。

于 2013-02-20T05:57:25.393 に答える