1

複数のクライアントにサービスを提供するWCFサービスがあります。「提案された一致を受け入れる」または「提案された一致を拒否する」のような操作があります。すべての操作を順番に実行したいのですが、パフォーマンスに影響が出るのではないかと思います。

私が見たところ、デフォルトの(そして最も使用されている)インスタンス化は「呼び出しごと」であり、デフォルトの同時実行モードは単一です。

それで、並行性で「シングル」モードを使用する必要があるのは本当ですか?そして、それはどれほど悪い影響ですか?

(私はせいぜい数十のクライアントがシステムを使用していると見積もっています)。

両方の世界を楽しむ方法はありますか?

並列コンピューティング(サービスはデータベースと通信します)を使用し、それでも操作をシリアルに実行しますか?

この投稿では、「インスタンスモード=呼び出しごとおよび同時実行性=単一」について読みました。

  • クライアントインスタンスごとに、単一のスレッドが割り当てられます。
  • メソッド呼び出しごとに、新しいサービスインスタンスが作成されます。
  • 単一のスレッドは、単一のクライアントインスタンスから生成されたすべてのWCFインスタンスを提供するために使用されます。

これは、操作呼び出しが連続して実行されることを保証するものではないようです。

たとえば、これが発生した場合:

  1. CLIENTALPHAは「操作A」を呼び出します
  2. CLIENTALPHAは「オペレーションB」を呼び出します
  3. CLIENTBETAは「オペレーションC」を呼び出します

私が読んだところによると、「単一のスレッドは、単一のクライアントインスタンスから生成されたすべてのWCFインスタンスを提供するために使用されます」と書かれています。これは、CALL1とCALL2がシリアルに実行されることを意味しているように聞こえますが、CALL 3は異なるクライアントスレッドからのものであるため、それらの間で実行される可能性があります。

これは本当ですか ?呼び出しが到着した順序で処理されることを確認する方法はありませんか?

そして、それが悪い習慣であるかどうか、またはWCFでこの通信方法を使用することが受け入れられ、推奨される実際のシナリオがあるかどうかを誰かに教えてもらえますか。

どうもありがとうございます

4

1 に答える 1

2

この質問に答えるには3つの方法があると思います

  1. 直接の答え
  2. クライアントとサーバーを制御する状況のための代替アプローチ
  3. クライアントを制御しない別のアプローチ

最初に2と3の答えを出したいのですが(私はそれらの方が良いと思うので)、最後に直接答えます...約束します!

あなたの問題は、サービスが受信した順序でメッセージを処理する必要があるということではないと思います。独立したクライアントがあるため、メッセージがサービスから送信されたのと同じ順序で受信されることを保証できないということです。クライアント

クライアントのアルファとベータの例を考えてみましょう。クライアントALPHAがオペレーションCを呼び出す前に、クライアントALPHAがオペレーション2を呼び出す要求を送信する場合でも、サービスが受け取る順序を知る方法はありません。これは、受信した順序でサーバーで処理したとしても、これは「間違った」順序である可能性があることを意味します。

これに同意する場合は、読み続けてください。そうでない場合は、この投稿の下部にある直接の回答に直接進んでください; o)

アプローチ1:WSトランザクションを使用する

サービスとクライアントの両方を制御し、クライアントがWS- * SOAPプロトコルを実装できる場合(.Net WCFクライアントなど)。次に、WS-Transactionプロトコルを使用して、単一の長時間実行トランザクションで処理されることを目的とした単一のクライアントからの操作が確実にそのように実行されるようにすることができます。

WCFを使用してWS-Transcationを実行する方法の詳細については、以下を参照してください。

http://msdn.microsoft.com/en-us/library/ms752261.aspx

クライアントALPHAとBETAの例に従うと、これによりクライアントALPHAは次のことが可能になります。

  • トランザクションを開始します
  • 操作1を呼び出す
  • 操作2を呼び出す
  • トランザクションをコミットする

クライアントでトランザクションを開始するALPHAの効果は、そのトランザクションをサーバーにフロースルーすることです。これにより、操作1と操作2が一緒に完了するか、まったく完了しないことを保証するDBトランザクションを作成できます。

これが行われている間にクライアントBETAが操作3を呼び出すと、トランザクションがコミットまたは中止されるまで待機するように強制されます。これにより、操作3がタイムアウトになる可能性があることに注意してください。その場合、BETAはそのエラーを処理する必要があります。

この動作は、またはのいずれInstanceContextModeかで機能しますConcurrencyMode

ただし、欠点は、この種の長時間実行される分散トランザクションは、一般的にスケーラビリティに適していないことです。現在、数十人のクライアントがいますが、将来的には成長しますか?そして、クライアントは常にWS-Transactionを実装できますか?もしそうなら、これは良いアプローチかもしれません。

アプローチ2:「楽観的な」タイプのアプローチを使用する

多くの異なるクライアントタイプ(電話、ブラウザなど)をサポートする必要がある場合は、操作を任意の順序で実行できるようにし、サービスとクライアントロジックが障害を処理できるようにすることができます。

これは悪いように聞こえるかもしれませんが、

  • サーバー側でデータベーストランザクション(上記のWS-Transactionトランザクションではない)を使用して、データベースが常に一貫していることを確認できます
  • 各クライアントは独自の呼び出しを同期できるため、この例では、ALPHAは呼び出し1がOKを完了するのを待ってから、呼び出し2を実行します。

ここでの欠点は、必要な障害ロジックについて慎重に検討し、クライアントとサービスのコードが堅牢で適切に動作することを確認する必要があることです。

あなたの例では、ALPHAはそれ自体の呼び出しを同期できると述べましたが、ALPHAが操作1を呼び出した後、操作2を呼び出す前に、BETAが操作3を呼び出す場合、それは次のようになります。

  1. 操作2は失敗します(たとえば、操作3が操作2が更新しようとしているレコードを削除した場合)。その場合、その失敗を処理する必要があります。
  2. 操作3は操作3を上書きします(たとえば、操作3はレコードを更新し、操作2は同じレコードを更新しようとします)。この場合、あなたは何をすべきかを決める必要があります。操作2を成功させることができます。その場合、ベータ版からの更新は失われます。または、操作2で、レコードがALPHAによって読み取られてから変更されたことを検出して失敗するようにするか、ユーザーに通知して、変更を上書きするかどうかを決定させることができます。

MS Entity Frameworkのコンテキストでのこれに関する議論については、を参照してください。

http://msdn.microsoft.com/en-us/library/bb738618.aspx

それの一般的な議論については、を参照してください。

http://en.wikipedia.org/wiki/Optimistic_concurrency_control

ConcurrencyMode繰り返しになりますが、WCFの用語では、これはどのInstanceContextMode

この種のアプローチは、スケーラビリティが重要な場合に使用される最も一般的なアプローチです。これの欠点は、ユーザーエクスペリエンスが低下する可能性があることです(たとえば、ユーザーが気付かないうちに変更が上書きされる可能性があります)。

元の質問への直接回答

メッセージが連続して処理されることを確実に確認する必要がある場合は、あなたが探していると思いますInstanceContextMode.Single

http://msdn.microsoft.com/en-us/library/system.servicemodel.instancecontextmode.aspx

これは、サービスクラスの単一のインスタンスがサービスアプリケーションの存続期間中に作成されることを意味します。ConcurrencyMode = Singleまたはを使用する場合ConcurrencyMode = Reentrantは、サービスが一度に1つのメッセージのみを処理し(インスタンスが1つあり、シングルスレッドであるため)、メッセージは受信された順序で処理されることを意味します。

を使用するConcurrencyMode = multiple場合、単一のサービスインスタンスは、異なるスレッドで同時に複数のメッセージを処理するため、処理の順序は保証されません。

これがパフォーマンスにどの程度の悪影響を与えるかは、各サービス呼び出しの実行にかかる時間によって異なります。1秒あたり10を取得し、それぞれが0.1秒かかる場合は、問題ありません。1秒あたり20を取得し、それぞれが通常0.1秒かかる場合、平均時間は100%増加します。

于 2012-04-27T22:14:21.930 に答える