21. Trwałe powiadomienia
A JEŚLI NIE DOSTARCZYMY POWIADOMIENIA OD
RAZU?
• Http API dla niedostarczonych powiadomień
• Stanowią mechanizm zastępczy dla usługi
socket’owej
• Kopia powiadomień w trwałym miejscu
25. Rozszerzenie AMQP
/php-amqplib/php-amqplib /pdezwart/php-amqp
• Biblioteka implementująca
protokół AMQP
• Interfejs PHP dla
rozszerzenia librabbitmq
Napotkane problemy:
• Brak pełnego potwierdzania
wiadomości
• Słaba kontrola w przypadku
problemów z RabbitMq
Napotkane problemy:
• Brak pełnego potwierdzania
wiadomości
• Słaba kontrola w przypadku
problemów z RabbitMq
26. Potwierdzanie / wydajność
TEST NA KLASTRZE 3 NODE’ÓW
BEZ POTWIERDZANIA
KLIENT W LOKALNEJ SIECI
11000 / s
Z POTWIERDZANIEM
750 / s
// w trakcie badania
możliwych optymalizacji
32. Federation
OFICJALNE ROZSZERZENIE
RABBITMQ
• Umożliwia przenoszenie wiadomości pomiędzy usługami (klastry, vhosty)
• Wymaga tej samej nazwy exchange zdalnego i lokalnego
• Mapowanie exchange’y poprzez wyrażenie regularne
• Konfiguracja poprzez panel RabbitMq lub API
• Automatyczne odbudowywanie powiązań w przypadku awarii
35. Testy – integracyjne
KILKA ŚRODOWISK TESTOWYCH
TESTY API POPRZEZ KLIENTA
HTTP
KLIENT POWIADOMIEŃ
Odizolowane, umożliwiające weryfikację
poprawnej integracji systemów
Niezależny klient odpytujący non-stop
wszystkie usługi i według scenariuszy
Niezależny klient powiązany z klientem
HTTP weryfikujący poprawność
otrzymywanych powiadomień
37. Testy – symulacyjne
• Analogiczny klient, ale pozbawiony UI
• Nie można uruchomić ich zbyt wiele z racji na wymagane zasoby
• Klient gry wyposażony w UI realizuje określone scenariusze
raportując błędne odpowiedzi webservices
• Można uruchomić ich dużo (bardzo) generując więcej
losowych, trudnych do przewidzenia sytuacji
BOTY – BEZ UI
BOTY – Z UI
38. Monitoring operacji asynchronicznych
CO MOŻEMY
SPRAWDZAĆ
• Wyniki działania botów na produkcji
• Wypełnienie kolejek wiadomości
• Czas ostatniej przetworzonej wiadomości (per consumer)
• Metryki serwerowe (load, pamięć, zużycie dysk, IOPS)
• Metryki biznesowe np. Ilość przyznanych nagród w ciągu ostatniej doby
Jako GOG.com jesteśmy firmą działającą w przemyśle growym
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Przykład złego zastosowania.
Server gry chce zgłosić koniec rozgrywki do pewnej usługi.
Przetwarzamy żądanie, a potem chcemy spowodować:1) aktualizację profilu użytkownika pod kątem zmiany doświadczenia, levelu itd.
2) Zdecydować o ewentualnych przynależnych nagrodach i dostarczyć je
Jakie mogą być problemy?
Jeśli dowolna z usług 2 i 3 nie działa to nie możemy poprawnie zakończyć gry
Możliwe, że niesprawność usługi 2 powoduje złe decyzje ze strony usługi 3
Request jest długi, bo zawiera dużo logiki, co zajmuje procesy PHP i tym samym blokuje kolejne zapytania + może powodować timeouty
Rezultaty zapytań są potrzebne do pokazania kolejnego ekranu gry.
Przykład złego zastosowania.
Server gry chce zgłosić koniec rozgrywki do pewnej usługi.
Przetwarzamy żądanie, a potem chcemy spowodować:1) aktualizację profilu użytkownika pod kątem zmiany doświadczenia, levelu itd.
2) Zdecydować o ewentualnych przynależnych nagrodach i dostarczyć je
Jakie mogą być problemy?
Jeśli dowolna z usług 2 i 3 nie działa to nie możemy poprawnie zakończyć gry
Możliwe, że niesprawność usługi 2 powoduje złe decyzje ze strony usługi 3
Request jest długi, bo zawiera dużo logiki, co zajmuje procesy PHP i tym samym blokuje kolejne zapytania + może powodować timeouty
Rezultaty zapytań są potrzebne do pokazania kolejnego ekranu gry.
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Promisy itd..
Promisy itd..
Ogólny model komunikacji asynchronicznej
Głównie Symfony + PHP7 (nie HHVM),
Korzystaliśmy z HHVM i było szybko ale:
warmup aplikacji był dużym problemem – był w trakcie deploy, ale nie rozgrzewał wszystkiego, dużo timeout’ów (powyżej 5sek)
Problem ze wsparciem dla dodatkowych kompilowanych bibliotek
Głównie Symfony + PHP7 (nie HHVM),
Korzystaliśmy z HHVM i było szybko ale:
warmup aplikacji był dużym problemem – był w trakcie deploy, ale nie rozgrzewał wszystkiego, dużo timeout’ów (powyżej 5sek)
Problem ze wsparciem dla dodatkowych kompilowanych bibliotek
Trwałość – zapis na dysku, na zreplikowane na node’ach klastra
Potwierdzanie
Skalowalność – wiele node’ów w klastrze
Wystarczająca wydajność – wyniki testów async? (Kafka być może szybsza, ale mniej niezawodna)
With use_socket set to false producing messages (to rabbit that does not respond) will cause destructor to hang infinitely.
With use_socket set to true
consumers will not be blocking (they will crash after 1s of being idle)
producers will work and use timeout, but they will simply ignore all errors (there's no way to tell that the message wasn't delivered)
This bundle doesn't use confirm channels nor transactions, so basically rabbit does not guarantee that the message was delivered anyway.
php-amqplib is poorly written and poorly maintained. It's incoherent, there's no way to tell which behavior was intended, and it often introduces regressions. I think original authors did not understand how sockets work.
We could probably fix those two problems (timeouts and lack of confirmation), but I still think it's unwise to use php-amqplib, plus I wouldn't bother with pull request since it's better to not trust their commits.
PHP extension ( http://php.net/manual/pl/book.amqp.php ) has outdated documentation and isn't available for hhvm.
TBH I think we should look into "Pattern: reliable queue" here: http://redis.io/commands/rpoplpush, or write our own amqp lib and fork rabbitmq bundle.
Możiiwy także crash w trakcie przetwarzania
Co w sytuacji gdy nie działa Redis? (jest tylko dodatkową warstwą zabezpieczenia przed błędem RabbitMq, więc jak nie działa to ok)
Motywacja dla takiego a nie innego flow
Limit ponowień
Dynamiczny delay -> 5, 100, 600, 3600 sek.
Deadletter bez consumera
Deadletter dla malformed messages
Delay – natywny mechanizm RabbitMq poprzez TTL
Odseparowanie usług
Zachowana logika zarządzania – klient pyta o login, hasło i nazwę exchange i potem sam sobie ogarnia
Czemu nie Shovel? Bo jego funkcje zawierają się Federation, Shovel nie ma API
Dlaczego nie, dlaczego nadal coś może pójść nie tak
Ogólny model komunikacji asynchronicznej
Ogólny model komunikacji asynchronicznej
Dlaczego nie, dlaczego nadal coś może pójść nie tak