GWINT: Przetwarzanie rozproszone z wykorzystaniem komunikacji asynchronicznej w grze online (PHPCon...

Post on 21-Jan-2017

164 views 0 download

Transcript of GWINT: Przetwarzanie rozproszone z wykorzystaniem komunikacji asynchronicznej w grze online (PHPCon...

Krzysztof Sobczak, Software Engineer - Gwent Webservices

Przetwarzanie rozproszone z wykorzystaniem

komunikacji asynchronicznej w grze online

GWINT webservices – GOG

POKRYWAJĄ M.IN.:

• NAGRODY I OSIĄGNIĘCIA

• MIKROTRANSAKCJE

• ELEMENTY MULTIPLAYER

• PROFILE GRACZY

• KOLEKCJE KART

Synchroniczna komunikacja HTTP

Synchroniczna komunikacja HTTP – przykład 1

Synchroniczna komunikacja HTTP – przykład 1

Synchroniczna komunikacja HTTP – przykład 2

Synchroniczna komunikacja HTTP – przykład 2

Asynchroniczna komunikacja

Asynchroniczna komunikacja - przykład

Na które powiadomienia czekać?

Łańcuch powiadomień

Łańcuch powiadomień

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

Technologie

System kolejkowy

KLUCZOWE ASPEKTY

• Potwierdzanie produkcji / konsumpcji wiadomości

• Wystarczająca wydajność

• Trwałość wiadomości

• Skalowalność

Rozszerzenie AMQP/php-amqplib/php-amqplib /pdezwart/php-amqp

• Biblioteka implementującaprotokół AMQP

• Interfejs PHP dla rozszerzenia librabbitmq

Napotkane problemy:

• Brak pełnego potwierdzaniawiadomości

• Słaba kontrola w przypadku problemów z RabbitMq

Napotkane problemy:

• Brak pełnego potwierdzaniawiadomości

• Słaba kontrola w przypadku problemów z RabbitMq

Potwierdzanie / wydajność

TEST NA KLASTRZE 3 NODE’ÓW

BEZ POTWIERDZANIA

KLIENT W LOKALNEJ SIECI

11000 / sZ POTWIERDZANIEM

750 / s// w trakcie badania

możliwych optymalizacji

Duplikacja wiadomości

Duplikacja wiadomości

Ponawianie wiadomości

Kolejki w mikroserwisach

Kolejki w mikroserwisach

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

System powiadomień

Case study: system powiadomień #1

Case study: system powiadomień #1

• Kolejki tworzone po ustanowieniu połączenia z użytkownikiem

RABBITMQ

• Kolejka per użytkownik [~500k ]

• Kolejki usuwane po zerwaniu połączenia z użytkownikiem

PROBLEM?

• Restart Node.js oznacza ~500k kasowanych/tworzonych kolejek

• Za duże obciążenie Node.js w trakcie inicjalizacji• Przy więcej niż jednym node w klastrze restart potrafi trwać nawet 30min!

Case study: system powiadomień #2

Case study: system powiadomień #2

• Kolejka per użytkownik [~500k]

REDIS

• Wydajność 10k połączeń / s po restarcie klastra

• Publikacja do wszystkich podłączonych klientów

• Utrzymuje bez problemów kilkaset tysięcy połączeń

• Mechanizm Publish / Subscribe

• Konsumuje zdecydowanie mniej zasobów niż RabbitMq

Case study: system powiadomień #2

Case study: system powiadomień #2

• Na potrzeby kompresji bufor ok. 4K per połączenie (kilkaset tysięcy)

PROBLEM #2 Z NODE.JS

• Ogromne zużycie pamięci sięgające 20GB

• Wystarczyło wyłączyć kompresję (wiadomości i tak są małe)

• Wycieki pamięci widoczne po dniach/tygodniach

• Nadal duże obciążenie w przypadku restartu Redis

PROBLEM #1 Z NODE.JS

• Trudność debugowania aplikacji w środowisku produkcyjnym

Case study: system powiadomień #3

Case study: system powiadomień #3

• Brak nadmiarowego obciążenia po restarcie Redis

• Brak problemów z pamięcią i procesorem

• Okazał się przystępniejszy w rozwijaniu niż Node.js

GOLANG

• Prostsze debugowanie na produkcji (np. podgląd goroutines)

Problem wersjonowania

WERSJA ???

WERSJA 1

Problem wersjonowania

• Możliwe, że wiadomość została rozpoczęta po stronie serwerowej –wtedy brak informacji o wersji

• Propagacja informacji o wersji razem z wiadomością

• Możemy skorzystać z wersji ostatnio używanej przez użytkownika

ROZWIĄZANIE #2

ROZWIĄZANIE #1

Kontrola sesji użytkownika

W JAKI SPOSÓB MOŻNA ZAPEWNIĆ,

ŻE W DANEJ CHWILI

UŻYTKOWNIK MA TYLKO JEDNĄ SESJĘ GRY?

Kontrola sesji użytkownika - powiadomienia

Testy – dev

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ń

Czy to wystarczy?>NIE<

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

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

Case study: matchmaking

Case study: matchmaking #1

Case study: matchmaking #2

Case study: matchmaking #3

Podsumowanie

• Poprawić niezawodność usług• Zwiększyć skalowalność aplikacji• Jeszcze bardziej odseparować mikroserwisy

ASYNCHRONICZNOŚĆ POZWOLIŁA NAM:

PYTANIA?

Dołącz do nas!

1500+Gier w portfolio

5M+Unikalnych użytkowników / m-c

GOG.com – O NAS

Care about games. Care about gamers.

#1 Alternatywa dla Steam’a

DZIĘKUJĘ ZA UWAGĘ