Przygotowanie mikroserwisu pod duży ruch

1

Załóżmy że stworzyłem aplikacje z której dziennie korzysta miliony użytkowników.
Jakie kroki muszę przedsięwziąć żeby mój backend był w stanie obsłużyć tak duży ruch?
REST API Springowe z tego co wiem obsługuje wiele zapytań na raz. Kwestia czy sobie poradzi?
Baza danych zapewne nierelacyjna + żeby obsługiwała asynchroniczne zapytania - MongoDB ?
Co jeszcze? Jakieś konkretne narzędzia na około?

5

No i load balancer i tyle instancji aplikacji ile będzie konieczne. Co do bazy to zależy jakie dane. Są klastry baz relacyjnych które to uniosą . No chyba że nie potrzebujesz ACID

4
  1. Clean code. Bardzo łatwo optymalizować czysty kod i bardzo trudno wyczyścić zoptymalizowany kod.
  2. Metryki, metryki, metryki.
    Musisz wiedzieć gdzie są bottlenecki w aplikacji.

3 Zależnie od usecase:

  • optymalizacja najwolniejszych zapytań SQL,
  • optymalizacja hibernate (hypersystence optimizer)
  • cache
  • monitorowanie pul wątków np. Tomcatowej
  • stronicowanie odpowiedzi z API
  • CloudFlare, aby unikać DDOS
  • Cache na HTTP np. etag
  • Monitoring JVM. Garbage collector, JIT i ustawienie dobrych flag przy uruchomieniu,
  • Optymalizacja pul połączeń do bazy danych,
  • Circuit breaker / Retry tam gdzie potrzeba.
  1. Co do bazy to bym nie szalał. Każdy SQL daje radę dla 80% use case.
2

Z pytania wnioskuję, że nawet nie wiesz, że pod spodem jest serwer HTTP i na jakiej zasadzie on działa :) zacznijmy od tego, żeby ustalić na jaki ruch musisz się przygotować - najlepiej reads i writes per second w peeku ruchu. Możesz obsługiwać milion userów i mieć 10 rps, a możesz mieć i 10000. Do tego jaki jest czas odpowiedzi usługi (p99).

Po drugie, relacyjne bazy również się skalują. Np. taki Instagram korzysta z Postgresa.

Ponadto, abstrahując od Springa i JVM:

1
Charles_Ray napisał(a):

Z pytania wnioskuję, że nawet nie wiesz, że pod spodem jest serwer HTTP i na jakiej zasadzie on działa :) zacznijmy od tego, żeby ustalić na jaki ruch musisz się przygotować - najlepiej reads i writes per second w peeku ruchu. Możesz obsługiwać milion userów i mieć 10 rps, a możesz mieć i 10000. Do tego jaki jest czas odpowiedzi usługi (p99).

Po drugie, relacyjne bazy również się skalują. Np. taki Instagram korzysta z Postgresa.

I wcale nie jest powiedziane, że w zależności o szczegółów nie udźwignie tego jedna maszyna.
Jak na razie OP kol @Korges nam skąpi szczegółów

Robiłbym sobie nadzieję na dużą ilość req/s z jednej maszyny na architekturze asynchronicznej: jak Spring to Webflux (i czy koniecznie Spring?), może Ratpack (wydaje się dobry w kategorii Clean Code) i konkurencyjne rozwiązania. Wiedza teoretycznya, nie z własnych doświadczeń.

0

Pytanie jest czysto teoretycznie. Interesuje mnie road-mapa która wskazuje konkretne drogi wraz z rozrostem systemu. Generalnie odpowiedz na pytanie udzielona, czas się wziąć ja zgłębianie wiedzy :)

1

Zalezy jaki ruch.

  • czy klienci moga miec dodatkowa logike czy tez uderzaja bezposrednio do apki?
  • czy sa peaki?
  • jaki jest maks czas odpowiedzi?
  • ile danych srednio jest na request/response?
  • jaki jest dopuszczalny procent requestow odrzuconych?
  • czy mozna wymagac od klientow retrajow?
  • czy dopuszczalny jest HTTP2?
  • czy polaczenie musi byc szyfrowane?
  • ile serwisow zewnetrznych trzeba wywolac srednio na request?
  • czy dopuszczalna jest ewentualna spojnosc danych?
  • jaki jest procent danych ktore sa statyczne?
  • jaki procent danych moze byc keszowany?

Co do roadmapy to zainteresuj sie haslami NoSQL, reactive i Spring Cloud.

3
  • Zapomnij o tym że masz jeden serwer na backendzie. Od początku zakładaj że będzie to N maszyn, za load-balancerem, do tego być może z autoscalingiem.
  • Nie napisałeś czy to będziesz np. w K8s wkładał - tam byś miał autoscaling za darmo.
  • Baza danych, co najmniej 2 instancje - a najlepiej to mieć mały klaster (3 instancje).
  • To co napisałem to nie po to żeby mieć 1M zapytań, to pewnie pierwszy lepszy laptop z serwerem w Go wyciągnie - tylko po to żeby mieć pole do manewru przy wdrażaniu i upgradach.
  • Aplikacja powinna być napisana w sposób bezstanowy (nie trzymać niczego w pamięci), jeżeli sesja użytkownika jest potrzebna to dojdzie Redis (dobry też jako cache). Dzięki temu łatwo będzie to scalować i przerzucać użytkowników pomiędzy instancjami serwera gdy pojawi się nowa.
  • Async lub RX to sposób na zwiększenie przepustowości jeżeli to musi być jeden serwer. Czytelność kodu ucierpi (choć niektórzy twierdzą że się poprawi), łatwość debugowania również.
  • Bez podania innych info - czyli co to za apka, jakie gwarancje daje na backendzie (czy to sprzedaje bilety czy serwuje reklamy, zgubiony zapis w #1 jest bolesny, w #2 nie), czy ruch jest ciągły czy skokowy (bilety) ciężko ocenić. Generalnie to o co pytasz to zadanie dla architekta i to nie na dzień tylko raczej na tydzień pracy lub więcej.
2

Nie da się odpowiedzieć nie znając charakterystyki ruchu i serwisu. Jedyne generalne zasady to:

  • bezstanowość tak bardzo jak się tylko da, dzięki temu możesz zrównoleglić aplikacje na wiele maszyn i postawic za load balancerem
  • operacje na ścieżce krytycznej robisz bez interakcji z czymś co jest "wolne", więc np. nie strzelasz do bazy albo do zewnętrznych serwisów

Cała reszta zależy od tego co robisz. Potrzebujesz low-latency? Ile czasu trwa jeden request? Jak kosztowne obliczeniowo są operacje które realizuje ten system?

1 użytkowników online, w tym zalogowanych: 0, gości: 1