web-dev-qa-db-ja.com

SOA例外処理を行うためのベストプラクティスは何ですか?

SOA例外を処理するようになったとき、私と私の同僚の間で起こっているいくつかの興味深い議論があります:

一方では、JCFのプログラミングWCFサービス3版での発言を支持します。

この章の冒頭で述べたように、クライアントがエラーを気にしたり、エラーが発生したときに何か意味のあることをしたりするのはよくある錯覚です。このような機能をクライアントに焼き込もうとすると、クライアントとオブジェクトの間に過度の結合が生じ、設計に関する深刻な問題が生じます。クライアントは、サービスと密接に結合されていない限り、サービスよりもエラーについてどのように知ることができるでしょうか?エラーがサービスの下のいくつかのレイヤーで発生した場合はどうなりますか?クライアントをそれらの低レベルレイヤーに結合する必要がありますか?クライアントはもう一度電話をかけるべきですか?どのくらいの頻度で、どのくらいの頻度ですか?クライアントはユーザーにエラーを通知する必要がありますか?ユーザーはいますか?すべてのサービスの例外を互いに区別できないようにすることで、WCFはクライアントをサービスから切り離します。クライアントがサービス側で何が起こったかについて知ることが少ないほど、相互作用はより分離されます。

反対に、私の同僚の提案は次のとおりです。

サービス指向のアーキテクチャを構築する際のベストプラクティスと一致せず、値を正しくキー入力しないなど、ユーザーが回復できる問題があるという一般的な考えを無視しているため、これは単に間違っていると思います。システム例外のみを考慮した場合、おそらくこの考え方は成り立ちますが、システム例外は例外ドメインの一部にすぎません。ユーザー回復可能な例外はドメインの別の部分であり、定期的に発生する可能性があります。サービス指向アーキテクチャを構築する正しい方法は、ユーザーが回復可能な状況をチェック済み例外にマッピングし、チェック済み例外をそれぞれクライアントにマーシャリングして、クライアントアプリケーションプログラマが適切に処理できる一意の例外としてマーシャリングすることです。根本原因のトラブルシューティングが容易になるように、すべてのランタイム例外をスタックトレースとともにシステム例外としてクライアントにマーシャルします。

これについてあなたがどう思うか知りたいのですが。

7
neolei

ユーザーが回復可能な例外は「例外」であってはなりません。例外は、 exceptional 状況の場合です。フォームフィールドでいくつかの文字を置き換えることは、予期して計画すべきことです。

「サービス指向アーキテクチャ」の背後にある推進力の一部は、サービスが再利用可能であるということです。確かに、可能性があるクライアントにメッセージを送信している...または別のサービス、オーケストレーションエンジン、イベントサブスクライバー、または自動化されたタスクやバッチジョブの可能性があります。これらのアクターは、可能性のあるをいくら詳細にしても、障害から確実に回復することはできません。多くの場合、彼らは一方向メッセージング(つまり、MSMQ)を使用しているかもしれません。その場合、フォールトを送信することを許可することさえできません。単にそのためのチャネルはありません。

発信者が実際にそれを受信できると仮定して、サービスが障害メッセージを送り返すことを決定したら、発信者が賢明に実行できることは、それが入っているトランザクションをロールバックすることです。

Juvalはまさにその通りです。障害メッセージをクライアント例外にマーシャリングすることは、他のすべてのオプション(つまり、未処理の例外)を使い果たした場合は問題ありませんが、サービスがあらゆる種類の詳細を提供しようとしても意味がありません。 なし。ユーザーはエラーメッセージを読んだり理解したりせず、スタックトレースが user の観点からのメリットであると考える場合、ユーザビリティに関する最初のことは理解できません。

Microsoft 実際には例外の詳細をフォールトに入れるように指示します 。しかし、しないでください。しないでください。それはあなたが本当にエラーを handling すべきであるときに怠惰で失敗することを奨励するだけです。私はその道を進んでいて、終わりのない苦痛と悲惨さの1つです。障害が発生するとサービスプロキシが永久に無効になるため、WCFでは特に危険です。特に、他の「ベストプラクティス」に従って依存関係の注入を行う場合、クライアントアプリを設計してこれから回復するのは非常に困難です。

あなたがすべき-いや、しなければならないすることはサービス側のエラー、通常は永続ストレージに送信され、バグレポートとして通知が送信されます。より洗練されたサービスバスアーキテクチャには、エラーを発生させるすべての元のメッセージを保持するエラーキューもありますエラー-少なくとも、エラー自体が必要です。 あなたはあなたが欲しい-あなたのユーザーではない。スタックトレースを提供するためにそれらに依存しないでください。そうすると、すでに失敗しています。

「ユーザー回復可能な例外」は、SOAには存在しません。 「利用者」が誰なのか、事前に分からないのでそんなことはありません。例外が回復可能な場合、それはメッセージの一部である必要があります-たとえば、XML形式:

<customerUpdateResponse customerId="123" status="notUpdated">
    <validationErrors>
        <requiredFieldMissing field="fullName"/>
        <maxLengthExceeded field="phone" maxLength="30" actualLength="45"/>
    </validationErrors>
</customer>

これは私の頭の上にありますが、うまくいけば、あなたはアイデアを理解するでしょう。 既知の文書化された理由で操作が失敗する可能性がある場合、その「失敗」は仕様の一部になります。この場合、メッセージは event whatevered /と返送しており、クライアントアプリケーションはこのデータを適切に解釈できます。重要なことは、それがcontractの一部であり、予期しない「プレスの停止」エラーではないということです。

WCFではフォールトコントラクトなどを使用できることがわかりましたが、正直なところ、要点はわかりません。本当に必要のないところに複雑さが加わっているだけです。 SOAP障害は、正直なところ、あらゆる角度から対処するためのお尻の痛みです。

前述のように、 any 応答を送信できない場合についても慎重に計画する必要があります。 Webサービスの散在を伴う「SOA」の駆り立ては、主にRPCスタイルである傾向がありますが、実際には、堅牢な高性能アーキテクチャを設計するための戦略としては不十分です。少なくとも私の意見では、SOAのキラー機能はパブリッシュ/サブスクライブです。これにより、 totally サービス自体を分離し、メッセージを共有することしかできなくなります。しかし、これにはコストがかかります。双方向通信を省略しなければなりません。イベントを消費した後にサービスに障害が発生したい場合は、まあ、すばらしいですが、誰も聞いていないでしょう。つまり、適切なロギングと例外通知が本当に重要です本当に

2番目のケースの適切な全体的な戦略は、回復不可能なエラーの一般化されたメッセージタイプを定義し(技術的にはFaultExceptionを使用するだけです)、すべての障害を障害キューに転送するコンポーネントをパイプラインにインストールします。 a)何も失わないようにし、(b)それらをすべて中央の場所に集めます。これにより、10の異なるサーバー上に30の異なるWebサービスがある場合、生活が非常に簡単になります。 WCFで グローバル例外ハンドラーをセットアップする を実行するのは非常に簡単です。FaultedServiceHostイベントにアタッチするだけです。 独自のIErrorHandler をインストールして、このすべてを行うこともできます before 障害が発生するまで-あなたの選択。

しかし、要約すると、重大な問題をプロアクティブに解決し、回復可能なエラーで失敗しないように、システムを計測します。エンドユーザーにとって、ダウンタイムはダウンタイムです。例外の詳細を開発者とサポートスタッフが見つけられるようにしますが、ユーザーに漏らさないでください。

10
Aaronaught

サービスの状態やトランザクションの実行に関するステータスを提供しないサービスは、ブラックボックスのようなものです。サービスの利用者と環境を監視する管理者は、物事が機能しているかどうかを知ることができません。

監視のためにサービスを計測するいくつかの手法があります。モニターがピックアップできる「I am alive」メッセージをサービスが送信するハートビートを実装できます。これは単純なタスクですが、サービスが機能しているかどうかは実際にはわかりません。サービスが実行されていて、メッセージを送信する機能があることだけです。ただし、これはOSレベルのモニターが示す以上のものです。初めてハートビートを検出したときに、監視用のサービスを自動的に登録するようにモニターを設定できます。

「ping」インターフェースと呼ぶ監視インターフェースを開発することもできます。 pingインターフェイスにメッセージを送信すると、インターフェイスは機能の内部検証を実行して応答できます。これは、サービスが単に稼働しているだけではありません。また、特定のトランザクションを一連のサービスに送信し、それらがトランザクションを実行する「合成トランザクション」のサポートを組み込むこともできますが、テストアカウントの更新など、ビジネスへの影響はありません。ただし、すべてのビジネストランザクションのコンテキストでサービスが適切に実行されているかどうかを確認するには、アプリケーションレベルの監視用のフレームワークを開発する必要があります。

アプリケーションレベルの監視には、各ビジネストランザクションに関するステータスデータが必要です。ビジネスコンテキストまたはトランザクションコンテキストでアプリケーションを監視する機能には、サービスの呼び出しに固有のトランザクションのステータスの詳細を示すメッセージを送信するためのサービス内の監視インターフェイスが必要です。これには、各サービスがビジネストランザクションの重要なステップでステータスメッセージを送信する必要があります。次に、リアルタイムビューアを作成して、ステータスメッセージ(メッセージのセマンティクス(トランザクションIDなど)に基づく)を複合アプリケーション内のサービスと関連付けることができます。これにより、SLA管理、障害追跡、および問題判別のためのビジネストランザクションのエンドツーエンドのビューが提供されます。

このフレームワークの実装に役立つ ユーティリティのセット を次に示します。私はこれらのユーティリティの構築を手伝いました。

0
eric roch