web-dev-qa-db-ja.com

非同期の内部通信を処理するためのベストプラクティス?

最近、クレジットカード処理のプロジェクトを完了しました。私が直面した困難の1つは、通知メッセージの遅延/起こりうる失敗の処理でした。最も複雑な例は次のとおりです。

  • 支払い要求を送信する外部システム
  • 私のシステムはその要求を支払いゲートウェイへの要求に変えます
  • ユーザーをゲートウェイに送信する
  • ユーザーが支払いを実行するのを待っている
  • ユーザーがシステムに戻ったが、システムが成功/失敗の通知を受け取るまで保留される
  • 失敗に応じてユーザーを外部システムに送り返す

さらに困難だったのは、通知の送信に失敗すると、ゲートウェイが15分ごとに何時間も通知を送信しようとすることでした。

保留中のトランザクションのデータベースレコードを使用して解決し、リターンからの成功と失敗を検出し、通知とトランザクション処理のための時間遅延リスナーを検出しました...

かなり難しい!

しかし、これは何億回も前に解決されたに違いないので、ベストプラクティスは何ですか?

私の将来は、これらすべてのシステム間の処理を記述し、時間遅延と起こりうるネットワーク障害を管理することになるので、ベストプラクティスに従いたいと思います。

本/記事の推奨事項は素晴らしいでしょう。

前もって感謝します!

10
user86928

分散システムを構築する場合、「同期」システムと「非同期」システムの違いは次のとおりです。同期システムには、計算時間とメッセージ配信時間に既知の上限があります。つまり、特定のイベントにこれらの既知の上限がない非同期システムがあります。それをどのように扱いますか?

  1. これらの非同期プロセスに確率的上限がある場合、timeoutsを使用して、システムを部分的に同期システム。支払いゲートウェイの98パーセンタイル応答時間が5秒の場合、5秒のタイムアウトにより、98%のリクエストが成功し、他の2%は失敗します。これは、このプロセスが成功または失敗するまでにかかる時間の既知の上限があることを意味します。これ確率論的障害検出は、非同期システムを同期システムに変えるための重要なツールです。

  2. これらのイベントの永続的なレコードを保持して、システム障害が発生した場合にシステム状態を回復できるようにします。支払いゲートウェイハンドラーがこれらのイベントを揮発性メモリに保持していて、それがクラッシュした場合、あなたは困惑しています。

  3. 基本的に、各複雑なトランザクションは、システム内でのメッセージ(イベント)の送受信に基づく一連の状態変換です。 「保留中のトランザクションの記録」を使用してこれを非公式にモデル化しているようですが、さらに進めることをお勧めします。管理する必要があるトランザクションごとに、正式な状態マシンを作成しますそれはそれを記述し、その現在の状態の永続的な記録を保持します。これらのステートマシンは理解しやすく、テストも簡単で、あなたとユーザーの両方にとってこれらのプロセスに必要な可視性を提供します。

システムの非同期性が高まるほど、これらの複雑なイベント状態変換を管理するときに、より正式かつ明示的になる必要があります。ここでは、タイムアウト、永続的なイベントロギング、およびステートマシンがベストプラクティスです。これが、Erlang OTPがアプリケーションの動作の多くを、たとえば、ステートマシンモデルに基づいている理由です。

参考までに、私は Introduction to Reliable and Secure Distributed Programming より良いものを見つけていません。同期システムと非同期システムの両方を第一原理から理解するための強力なアルゴリズムの基礎を提供します。

13
Rein Henrichs