11

シナリオ
アプリケーションのDBがダウンしました。これにより、DBへの重要なデータのコミットを担当するアクターが接続の取得に失敗します。

推奨される動作重要なデータは、将来
バックアップされるときにデータベースに書き込まれます。

現在の実装
アクターはDBExceptionをキャッチし、データをDBWriteFailedケースクラスにラップして、メッセージをスーパーバイザーに送信します。次に、スーパーバイザーは、system.scheduler.scheduleOnce(...)を使用して、将来のある時点(たとえば、1分)に別の書き込みをスケジュールします。これにより、DBが復旧するのを待っている間、サークル内でスピンしすぎないようにします。

この実装は確かに機能しますが、もっと良い方法があるのではないかと思います。

  • コミットが成功した後、コミットするアクターが元の送信者に応答する必要がある場合、プロトコルは少し厄介になります。
  • コミットしているアクターへのメッセージの通常のフローは決して抑制されず、アクターは新しいメッセージを喜んで処理し、メッセージのすべてのDBに接続できない可能性があります。
  • メッセージがこの再試行ループに長時間とどまると、コミットしているアクターのメールボックスが膨らみ始めます。このデータをコミットすることは重要ですが、過度のメモリ使用量が原因でアプリケーションがクロールして停止したりクラッシュしたりしても、問題はありません。

私はakkaの初心者であり、スーパーバイザー戦略に関してはほとんど経験がありませんが、この再試行ロジックの一部を処理するためにそれらの1つを活用できる可能性があると感じています。

このような問題を解決するためのakkaの一般的なアプローチはありますか?私は正しい方向に進んでいますか、それとも別の方向に向かっている必要がありますか?

どんな助けでも大歓迎です。

4

2 に答える 2

9

Akka Circuit Breakerを使用して、接続の試行を減らすことができます。スケジューラーを再試行キューとして使用する代わりに、アクター内のバッファー(最大サイズ制限付き)を使用し、サーキットブレーカーが再び閉じられたときにそれらを再試行します(onCloseコールバックはセルフアクターにメッセージを送信する必要があります)。別の方法として、回路ブレーカーを隠しメールボックスと組み合わせることができます。

于 2012-12-17T08:53:06.103 に答える
1

アプリに完全なフェイルオーバーを実装することを計画している場合

しないでください。

データベースフェイルオーバーの責任をアプリ層にまで広げないでください。アプリに関する限り、データベースは稼働していて、読み取りと書き込みを受け入れる準備ができている必要があります。

データベースが頻繁にダウンする場合は、データベースをより堅牢にするために時間を費やしてください(これについては、すでにWeb上に多数のリソースがあります。「レプリケーション」、「高可用性」、「負荷分散」、「クラスタリング」などの用語をWebで検索してください。 '、およびhighscalability.comで他の人の戦争の話から学びます)。それはすべて、DBの停止の原因が何であるかによって異なります(たとえば、DBマスターのNICを最大限に活用し、ネットワークでGZIPを有効にすることで問題を断続的に「修正」しました)。

このルートをたどると、関心の分離に固執したことをうれしく思います。

再試行ロジックの奇妙な散水を実装し、DBの電圧低下を処理することを計画している場合

アプリが代替データベースになることを期待していない場合は、Patrikの答えが最善の方法です。

于 2012-12-17T08:07:05.257 に答える