Najlepsza praktyka obsługi asynchronicznej komunikacji między urządzeniami?

10

Niedawno zakończyłem projekt obsługi przetwarzania kart kredytowych. Jedną z trudności, z którymi się spotkałem, była obsługa opóźnień / możliwych awarii powiadomień. Najbardziej złożonym przykładem było:

  • zewnętrzny system wysyłający żądanie zapłaty
  • mój system przekształca to żądanie w żądanie do bramki płatności
  • wysyłanie użytkownika do bramy
  • oczekiwanie na dokonanie płatności przez użytkownika
  • użytkownik wraca do mojego systemu, ale jest wstrzymywany do momentu otrzymania przez system powiadomienia o powodzeniu / niepowodzeniu
  • Odesłanie użytkownika do systemu zewnętrznego w zależności od awarii

Jeszcze trudniejszy był fakt, że w przypadku nie wysłania powiadomienia brama próbuje wysyłać powiadomienie co 15 minut przez kilka godzin.

Rozwiązałem go, korzystając z bazy danych zawierającej oczekujące transakcje, a następnie wykrywającej powodzenie i niepowodzenie po zwrocie oraz odbiornik z opóźnionym opóźnieniem do powiadamiania i obsługi transakcji ...

Racjonalnie trudne!

Ale musiało to zostać rozwiązane już za wiele razy, więc jaka jest najlepsza praktyka?

Widzę, że moją przyszłością będzie pisanie obsługi między tymi wszystkimi systemami oraz zarządzanie opóźnieniami czasowymi i możliwymi awariami sieci, dlatego chcę stosować się do najlepszych praktyk.

Zalecenia dotyczące książek / artykułów byłyby świetne.

Z góry dziękuję!

użytkownik86928
źródło

Odpowiedzi:

13

Podczas budowania systemów rozproszonych różnica między systemem „synchronicznym” a „asynchronicznym” jest następująca: System synchroniczny zna górne granice obliczeń i czasów dostarczania wiadomości. Zatem: masz system asynchroniczny, w którym niektóre zdarzenia nie mają tych znanych górnych granic. Jak sobie z tym radzisz?

  1. Jeśli te procesy asynchroniczne mają górne granice probabilistyczne , możesz użyć limitów czasu, aby system działał jak system częściowo synchroniczny . Jeśli czas reakcji 98. percentyla bramy płatności wynosi 5 sekund, to 5 sekundowy limit czasu spowoduje, że 98% twoich żądań się powiedzie, a pozostałe 2% po prostu się nie powiedzie. Oznacza to, że masz teraz górną granicę czasu, jaki zajmie ten proces, aby zakończyć się sukcesem lub niepowodzeniem. Ta probabilistyczna detekcja awarii jest kluczowym narzędziem do przekształcania systemów asynchronicznych w systemy synchroniczne.

  2. Przechowuj trwały rejestr tych zdarzeń, aby móc odzyskać stan systemu w przypadku awarii systemu. Jeśli moduł obsługi bramy płatności utrzymuje te zdarzenia w pamięci ulotnej i ulega awarii, oznacza to, że masz problemy.

  3. Każda złożona transakcja jest zasadniczo serią transformacji stanu opartych na wysyłaniu i odbieraniu wiadomości (zdarzeń) w systemie. Wygląda na to, że nieformalnie modelujesz to za pomocą swojego „zapisu transakcji oczekujących”, ale sugeruję pójść dalej: dla każdej transakcji, którą musisz zarządzać, utwórz formalną maszynę stanu, która ją opisuje i przechowuj trwały zapis jej bieżącego stanu . Przekonasz się, że te automaty stanów są łatwe do zrozumienia, łatwe do przetestowania i zapewniają bardzo potrzebny wgląd w te procesy zarówno dla ciebie, jak i twoich użytkowników.

Im bardziej asynchroniczny jest twój system, tym bardziej formalne i jawne musisz być, zarządzając tymi złożonymi transformacjami stanu. Limit czasu, trwałe rejestrowanie zdarzeń i automaty stanów są tutaj najlepszą praktyką. Dlatego na przykład Erlang OTP opiera swoje zachowanie aplikacji na modelu automatu stanów.

Dla porównania, nie znalazłem nic lepszego niż wprowadzenie do niezawodnego i bezpiecznego programowania rozproszonego . Zapewni to silną bazę algorytmiczną do zrozumienia systemów synchronicznych i asynchronicznych na podstawie pierwszych zasad.

Rein Henrichs
źródło