24時間365日実行する必要があるプログラムでの例外処理


14

処理できる例外のみをキャッチする必要があることを読みました。これにより、ベース例外クラス(この場合はC#)をキャッチするのは悪い考えです(他の理由に加えて)。現在、私はプロジェクトの一部であり、これまでのところ、キャッチされている基本例外以外は何も見ていません。そうするのは悪い習慣と見なされると述べましたが、応答は「このサービスは24時間365日実行する必要があるため、そうです」でした。

24時間年中無休で実行する必要のあるプログラムで例外を適切に処理する方法についての良い応答がなかったため、ここにいます。24時間実行する必要のある「重要な」プログラム/サービスの例外処理に対処する方法に関する情報/提案を見つけることができませんでした(この場合、サービスが1分間停止しても大丈夫かもしれません)または2つなので、重要ではありません)。私はそれがプログラムの正確な性質に依存することを理解しています。命にかかわる問題を引き起こす可能性のあるプログラムの要件は、オンラインゲームのログスキャナーとはまったく異なります。

2つの例:

1:イギリス鉄道の顧客向けの先行入力サービス。鉄道駅をオンラインで検索するときに使用されます。

2:線路、列車などのさまざまなセンサーから提供されるリアルタイム情報に基づいて、上記の鉄道の鉄道スイッチを自動的に制御するプログラム。

最初のプログラムが1、2分間停止しても、おそらく大きな問題は発生しませんが、後者は人的被害を引き起こす可能性があります。それぞれに対処する方法の提案?この問題に関する詳細情報と考えを見つけることができる場所へのポインター?


2
リアルタイムアプリでの例外処理中にスタックが巻き戻されると(原文のまま!)、列車が台無しになります。
鹿ハンター14年

4
@DeerHunter例外のない悪いコーディングは、同じ結果になる可能性があります。
BЈовић

9
さて、あなたcatch Exception。それはあなたのプログラムが機能することを意味するものではありません。それは、失敗が実行を続けている間にアプリケーションの状態を破壊させることを意味します。クラッシュしたプログラムは悲惨なものになる可能性がありますが、無効な状態ではあるがアクションを実行しているプログラムは積極的に悲惨なものになる可能性があります。
Phoshi

1
アプリケーションを24時間年中無休で実行する必要がある場合は、どこかに無限ループがあり、この無限ループは未処理の例外をすべてキャッチするコンストラクトにラップする方が適切です。そうでない場合、未処理の例外は、mainの外側にある既存のキャッチオールハンドラーに浸透し、kaboom!24時間年中無休のアプリケーションは終了します。
デビッドハンメン14年

回答:


7

のような特定の言語機能

  • ガベージコレクション
  • 例外システム
  • 遅延評価

一般に、リアルタイムシステムでは役に立ちません。おそらくこれらの機能のない言語を選択し、最大メモリ使用量や最大応答時間などの特定のプロパティを証明するようにしてください。


プログラムを継続的に実行する必要があるが、短期的かつ非グローバルな障害が許容される場合、Erlangのような戦略を使用できます。Erlangは、並行機能プログラミング言語です。通常、Erlangで記述されたプログラムは、互いに通信できる複数のワーカープロセスで構成されます(アクションモデル)。1つのワーカースレッドが例外を検出すると、再起動されます。これは短いダウンタイムを意味しますが、他のアクターは通常どおり続行できます。

これを要約すると:堅牢なプログラムでは、さまざまな部分が互いに分離されており、個別に再起動またはスケーリングできます。

基本的に、これと同等のコードが必要です。

while (true) {
  try {
    DoWork();
  }
  catch (Exception e) {
    log(e);
  }
}

さらに、ループを終了する方法。このようなループは、各ワーカースレッドを駆動します。


キャッチオール経由でエラーを無視する場合の問題は、プログラムの不変式がエラーの原因によって違反されている可能性があり、後続の操作が役に立たない可能性があることです。これに対する良い解決策は、独立した労働者間でデータを共有しないことです。ワーカーを再起動すると、必要な不変式がすべて再構築されます。つまり、メッセージの送信など、異なる方法で通信する必要があります。アクターの状態は、他のアクターの不変式の一部ではない場合があります。

あまりにも多くの例外をキャッチすることに関する別の問題は、そのような予防措置を講じている場合でも、すべての例外が再起動によって修正できるわけではないことです。それ以外の場合、メモリ不足などのハードな問題は、再起動することで処理できます。しかし、物理ケーブルが抜かれたときに再起動してもインターネット接続を回復するのに役立ちません。


1
はい。ただし、「物理ケーブルが引き抜かれた」ような状況は、誰かがケーブルを元に戻すまで例外ログを一杯にしたいときに、アプリケーションをさらに手動で再起動することなく、再び動作を開始します。
マークハード14年

2

あなたの質問に答えるには、例外とは何か、そしてそれらがどのように機能するかを理解する必要があります。

通常、例外は、ユーザーの支援が必要なエラーが発生した場合にスローされます。そのような場合、スタックを巻き戻して例外を処理するのにどれだけ時間がかかるかは関係ありません。

キャッチハンドラがない場合、プログラムは実行を停止します。セットアップと要件に応じて、受け入れられる場合があります。

特定の場合:

  1. クエリを実行できない場合(間違った都市名など)、ユーザーにエラーを通知し、修正するように依頼します。
  2. 重要なセンサーから情報を取得していない場合、オペレーターに問題の修正を求めずに続行することはあまり意味がありません。

つまり、どちらの場合でも、例外を使用する意味があります。RTプログラムでは、実行を継続できない深刻な問題のみを示すように注意してください。


1

私はこれまでのところ、キャッチされている基本例外以外には何も見ていません。

例外が適切に処理されていない限り、ここに問題があるように思えます。適切な時点で例外をキャッチし、適切なアクションを実行すると(例外のタイプに応じて)、サービスの信頼性がはるかに高くなります。

サービスを継続する必要がある場合、おそらく意図したとおりに機能していることが重要です。たとえば、鉄道の乗り換えを制御するプログラムが例外をスローした場合、安全関連センサーとの通信に問題があることを示している可能性があります。基本例外をキャッチして続行すると、サービスが実行される場合がありますが、意図したとおりに機能せず、災害につながる可能性があります。

あるいは、センサーとの通信障害があるときにスローされた例外をキャッチし、適切に処理する(つまり、影響を受ける地域で列車を停止する)場合、サービスは実行され、誰も殺していません。

そのため、質問を理解したときに、最初のインスタンスでは、base-exception-typeハンドラーを削除するよりも、より具体的な例外処理を追加することをお勧めします。


0

ポイント2に関しては、C#を使用しないでください。これは、リアルタイムの言語ではありません、あなたはなりますが、このようなとしてそれを使用しようとすると傷を取得します。

ポイント1については、アーランに行くことができます:クラッシュさせてから再起動する


私のC#の使用法と専門知識は、ポイント2(リアルタイムトラックスイッチング)の周辺ではありません。C#がこのようなタスクにあまり適していないのはなぜですか?
マイケルオニール14年

1
主に:ガベージコレクターは、時間に関してプログラムの動作を予測不能にします。また、ランタイムはあまりにも複雑で、あなたは物事をシンプルに必要とする状況で、彼らはより予測可能です
miniBill

0

免責事項:これらは単なる考えであり、経験はありません。

2番目の例の要件を満たすプログラムは、非常にモジュール化されている必要があります。そのため、システムを不安定にすることなく、モジュールを再起動できます。

たとえば、内部状態のアサートに失敗したオブジェクトは、破棄して再作成できるようにし、そのプロセスですべてのコンシューマとサプライヤに通知する必要があります。より具体的には、プログラムが鉄道のスイッチを制御しており、決定ループでアサートに失敗した場合、緊急モジュールを実行して、関連するすべての列車を停止し、メイン決定モジュールが再初期化されるのを待ちます。

より現実的には、冗長性を導入します -ハードウェアとソフトウェアの複製。1つのインスタンスは制御対象システムに配線され、もう1つのインスタンスはフリーランニングです。エラーが検出されると、システムが切り替えられます。

例としては、同じマシン上の2つのプロセスがあります。これらは相互に監視し、一方が殺されると、もう一方がそれを再生成し、その親PIDをそれ自体から分離します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.