いくつかのマイクロサービスが失敗した場合、それらを更新するソフトウェアをどのように設計しますか?


12

他のサービスが安定している間、ダウンまたはダウンするサービスを支援するために使用できる設計パターンまたはプラクティスはありますか?

3つのマイクロサービスがあり、そのうち2つが正常で、1つがPOSTの途中で停止した場合はどうなりますか?2つはPOSTを受け取り、1つは受け取りません。リクエストをサービスに発送しているため、取引ができないと思います。

そのためにどのように設計しますか?さまざまなデータベースに孤立したデータは必要ありません。


6
解決するのは簡単な問題ではありません。私はそれがサービスのキューとして実装されていることを見てきました(最終的な一貫性)、おそらくあなたはサービスを制御しておらず、トランザクションマネージャまたはトランザクション機能を課すことは最高のくだらないシュートであり、おそらく良い考えではないからですSOA環境で。これは、主に目的地への接続がある場合とない場合があるモバイルプッシュで見られました。
マイク

アシッド・オーバー・マイクロサービスはクラックするのが難しいナットです。別のオプションはバスの種類で、redisのパブリッシュ/サブスクライブまたはキュー設計を使用し、インバウンドチャネルから一度投稿してから、サブスクライブするサービスまたはサービスプロキシがターゲットにプッシュして成功を報告します失敗。障害を監視し、そのためのフローも用意する必要があります。また、トランザクションが1つのサービスでは有効ではなく、他の2つのサービスでは有効であるが、対処する必要がある別の障害フローだけである場合、障害が発生する可能性があります。
ティムセダーキスト16

「キューマネージャー」のようなものを使用しませんか?これは、Redisがボトルネックの原因になると思いますか?または、少なくとも高い可能性もありますか?あなたが説明した以外に方法はありません。
ジョニー

データフローの量に応じて、成功が報告されるか、失敗した通知をポストし、停止に関するSMSアラートを送信するまで送信を再試行するキューマネージャーを実装しました。予想される停止時間にも少し依存すると思います(どれくらいの時間)。
htm11h

これは、rabbitmqのようなものの目的ですか?
ジョニー

回答:


9

いくつかのオプション。

永続的な通信チャネルを使用する

HTTPの代わりに、高可用性で永続的なキューにメッセージをドロップします。例えばカフカ。ターゲットサーバーが何らかの時点で利用可能になる限り、メッセージを取得します。

複雑なサブシステム(キュー)のプロビジョニングと管理のトレードオフがあります。したがって、これが価値があるかどうかを分析してください。

バックオフと再試行

呼び出し元に、失敗した要求(おそらくディスクに永続化される)を保持させ、定期的に再試行してください。この場合、クラッシュを引き起こすリクエストとサービスが停止していることを区別することが重要です。前者はおそらくバグが原因であり、ログに記録する必要があります...修正が行われるまで再試行はおそらく違いはありません。

検出および補正

定期的なタスクは、マイクロサービス間の一貫性条件をチェックします。たとえば、障害は、必要に応じて直接APIクエリまでログを記録します。問題が見つかった場合(たとえば、注文はあるものの、出荷リストに梱包リストが届いていない場合)、補償手順を行います。これらの手順は、手動で修正するためのサポートチケットを作成するか、誰かにメールを送信することなどです。

設計の代替案を検討する

このようなケースでは、影響を受けるマイクロサービスへの呼び出しを管理するために、おそらくAPIゲートウェイが必要です。このようにして、この問題を軽減するために使用する戦術を制御します。おそらく、これらの実装の詳細をクライアントに負担させたくないでしょう。サーキットブレーカパターンを参照してください。

マイクロサービスは独立しているため、一貫性を失わせる可能性のある障害が常に存在します。それらが発生した場合、手動で修正する準備をする必要があります。

強力な一貫性が必要な場合、マイクロサービスは適切ではありません。スケーラビリティが必要な場合は、一貫性を保証するために、関連するデータを同じシャードに配置できるシャーディングを検討することをお勧めします。シャードを追加してIOをスケールアウトすることもできます。

強力な一貫性が必要で、スケーラビリティの問題がない場合は、モノリシックサービスを使用してください。ライブラリをアプリケーション内の境界として使用して、懸念事項を分離します。


これはRabbitMQの目的ですか?
ジョニー

RabbitMQはあなたの質問の答えですか?いいえ、それはあなたのニーズを満たすソリューションの一部かもしれませんが、あなただけの問題を解決するつもりはありません。
ケイシースピークマン

ちょっとだけ。RabbitMQはメッセージを永続化しないと思います。消費されてキューから削除されるため、NO。永続化と再試行が必要な場合、RabbitMQは役に立ちません。
ライヴ

2

あなたが説明しているのはコンセンサス問題だと思います:分散トランザクションの各参加者が操作が成功したと言わない限り、コミットしたくないでしょう。これに対する簡単な解決策は、2フェーズコミットです。基本的に、各システムでステージングが成功したと報告されるまで、各システムでトランザクションをステージングします(フェーズ1)。トランザクションのすべての参加者が成功を返した場合、各参加者はコミットするように指示されます。それらのいずれかが代わりに失敗を返した場合、ロールバックが発行されます(フェーズ2)。これには、より複雑な3フェーズコミットソリューションにつながるしわがあります。それぞれのより良い説明をここで読むことができます:

http://the-paper-trail.org/blog/consensus-protocols-two-phase-commit/

http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/

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