例外処理
Photon3.0では、例外処理が完全に再設計されました。
以前のバージョンの戦略では、Photon Framework内(photonsocketserver.dll) ですべての例外を探知し、 ロギングファサードによってそれらをログに記録していました。
しかし、この設計には以下のような欠点がありました:
- 未処理の例外イベントハンドラーが呼び出されない:
予期されるCLRのデフォルトの挙動は、ディベロッパーのコードによって例外が処理されない場合に、未処理の例外イベントハンドラー上で通知されることです。 - 例外処理のログへの依存:
開発者は 例外の「欠損」を防ぐためにロギングファサードを実装する必要があります。 - 未処理の例外の唯一の挙動:
ディベロッパーによって処理されない例外は、Photonによって取得およびログに記録され、無視されていました。
.NET 1.xの「ランタイムバックストップ」は 同様の方法で効果的に動作しました。 - 一貫性の無い挙動:
ディベロッパーが制御するスレッドで処理されない例外によって、未処理の例外ハンドラーが発生し処理が停止しました。
Photon 3.0の新機能
- 未処理の例外イベントハンドラーは必ず呼び出されます:
ディベロッパーのコードで処理されない例外は、 必ず未処理の例外イベントハンドラーを発生させます。 - 非侵入型ロギング:
ディベロッパーには未処理の例外ハンドラーの実装を推奨していますが、 開発者のコードには関係なく、処理されない例外はPhotonによってログに記録されます。
詳細は「未処理の例外のロギング」を参照してください。 - 未処理の例外の3つのポリシー:
未処理の例外が発生した場合、Photonは以下の3つのポリシーのいずれかで対応します - 無視、アプリケーションを再起動、処理の終了。 - 一貫性のある挙動
例外処理ポリシーがCLRによってオーバーライドされる例がいくつかあります:
- ThreadAbortException は、必ずしもプロセスを再起動または終了するとは限りませんーExceptions in Managed Threadsを参照してください。
- StackOverflowExceptionは無視できませんーStackOverflowException Classを参照してください。
例外のスローと開発者の処理のベストプラクティスは、 以下のページ「Exception Handling Best Practices in .NET」を参照してください。
legacyUnhandledExceptionPolicy
)は、Photonではアプリケーション設定ごとにはサポートされていません。このモードはインスタンスごとに設定されます(UnhandledExceptionPolicy = "ignore"
)。「未処理の例外のポリシーの設定」を参照してください。
UnhandledExceptionPoliciesの使用の提案
マイクロソフトは.NET 2.0の新しいデフォルトポリシーとして「プロセスの終了」を 導入しました。以下は、「Exceptions in Managed Threads」からの引用です:
スレッドが暗黙的に失敗できる場合、 アプリケーションを終了しないと深刻なプログラミングの問題を検出できない場合があります。 これは長時間実行されるサービスや他のアプリケーション固有の問題です。スレッドが失敗すると、プログラムの状態は徐々に破損します。 アプリケーションのパフォーマンスが低下したり、 アプリケーションがハングアップすることがあります。
オペレーティングシステムがプログラムを終了するまでに未処理の例外をスレッドで自然に進行させると、開発およびテスト中にこのような問題が発生します。
プログラム終了のエラーレポートは、デバッグに対応しています。
プロジェクトの状況(開発中、QA中、既知の問題がなく本番で稼働中など)に応じて、Photonで対応している様々なポリシーのいずれかを適用すると良いかもしれません。
- アプリケーションを再起動
- 無視
- 処理を終了
開発
開発中に「処理を終了」を設定すると、処理終了中にデバッガ/visual studioが起動します。
マルチスレッド問題を処理する場合には、処理を実行し続けてアプリケーションを読み込んでから、ポリシー「無視」を適用したほうがよいでしょう。
QA
QA段階の場合には、負荷テストや手動テストの際に"処理の終了を使用すればルートエラーに起因する多くのエラーを受信せずにすみます。
本番環境で安定して稼動
サービスが安定している場合には、ポリシー「アプリケーションを再起動」を適用してください。
稀に発生する未処理の例外のイベントによって、Photonはアプリケーションを再起動し、リスクを最小化します。
これは、最短でシステムの再稼動を実現するための方法です。
**「処理の終了」"**ポリシーによってPhotonをサービスとしてセットアップし、またWindowsサービスを自動的に再起動するよりも早く再起動できます。
**注:**この事象がより頻繁に発生する場合には、サービスおよびログファイルを監視する必要があります。
既知の問題があり、本番環境で稼動
システムが予期せぬ例外を頻繁に表示し、修正に時間を要する場合にはー例外の内容によりますが、ポリシーを「無視」に設定すればシステムの安定性を維持できる場合があります。
StackOverflowsについての注
通常、未処理の例外の際にログを記録されたスタックトレースによって、修正すべき点を把握できます。
StackOverflowExceptionとは、未処理の例外のポリシーが「無視」または「RestartApplication」に設定されて、スタックトレースが欠損した可能性がある状態を指します。
デバッグの手順については、「Photon Serverの Stackoverflow」ページを参照してください。
コアのデバッグについての注
稀にPhotonコアによって予期せぬ例外が発生する場合があります。この場合には、設定「ProduceDump」をTRUE
に設定してください(Photon コアのデバッグ)。
問題を解決するため、生成されたダンプファイルとログを弊社に送信してください。
未処理の例外のロギング
下図に示したとおり未処理の例外イベントは、まずカスタムアプリケーションのコンテキストで発生します (1)。ディベロッパーは希望する方法で、例外をロギングできます c)。
ロードバランシングのサンプルコードも参照してください。
次のステップで、CLRはデフォルトのアプリケーションドメインでイベントを発生させます。(2)―
これはPhotonの場合はPhotonHostRuntimeです。 このため、Photonは(b)でログに例外を記録することができます。
Photon Loggingfile default path/filenames Photon Loggingfile のデフォルトのパス/ファイル名
a [$PhotonBaseDir]\bin_[$OS]\log\Photon-[$InstanceName]-[$date].log
b [$PhotonBaseDir]\bin_[$OS]\log\PhotonCLR.log
c [$PhotonBaseDir]\log\[$ApplicationName].log
UnhandledExceptionポリシーの設定
XML
<Runtime
Assembly="PhotonHostRuntime, Culture=neutral"
Type="PhotonHostRuntime.PhotonDomainManager"
UnhandledExceptionPolicy="無視"
- UnhandledExceptionPolicy:
ReloadAppDomain
またはignore
またはTerminateProcess
。
Photonコアのデバッグ
XML
<!-- Instance settings -->
<Instance1
...
ProduceDumps = "TRUE"
DumpType = "Full"
MaxDumpsToProduce = "2"
...
- ProduceDumps:
TRUE
またはFALSE
。 - DumpType:
Full
またはMaxi
またはMini
。