Niecały projekt musi być elastyczny przy dużym ruchu
Czytam aktualnie książkę „Złożone zagadnienia architektury oprogramowania”. I jednym z tematów, które tam się pojawiają jest kwestia skalowalności i elastyczności architektury i aplikacji.
Za moment opiszę pokrótce różnicę między nimi. Jednak to, na czym chcę się dzisiaj skupić, to kwestia tego, że elastyczność naszej aplikacji, jeżeli chodzi o obsługę bardzo wzmożonego ruchu, nie musi oznaczać, że mamy od razu przygotowywać cały projekt tak, żeby jak najszybciej obsłużyć w pełni cały proces związany z tym ruchem.
Skalowalność, a elastyczność
Jest szansa, że zdarzyło Ci się usłyszeć o skalowalności w kontekście jakiegoś projektu aplikacji. Rozmawiamy o projekcie i opowiadamy, że nasza aplikacja jest skalowalna. Dostawcy rozwiązań chmurowych kuszą nas obietnicami o tym, że możemy wedle potrzeb skalować ich usługi.
Jednak czym tak naprawdę jest skalowalność i jak ma się do tego elastyczność? I dlaczego bardzo często słowo „skalowalność” jest używane błędnie?
Szczerze mówiąc, z pojęciem elastyczności spotykam się bardzo rzadko. Tak naprawdę, przed przeczytaniem książki „Złożone zagadnienia architektury oprogramowania” nie pamiętam za wiele momentów, kiedy to stwierdzenie bym słyszał w konkretnych rozmowach.
A to poważny błąd!
Autorzy książki dosyć jasno opisali różnicę między skalowalnością, a elastycznością.
W skrócie – skalowalność dotyczy bycia gotowym na rośnięcie naszej bazy użytkowników w dłuższym czasie, a elastyczność odnosi się do zmiany wielkości ruchu w danym momencie.
O skalowalnej aplikacji mówimy w momencie, kiedy jest ona w stanie obsługiwać coraz więcej użytkowników, czy operacji, wraz z rośnięciem naszego biznesu. Skalujemy projekt względem rosnącej popularności naszego rozwiązania. Jest to w miarę stale zwiększający się ruch, ilość danych, ilość operacji.
O elastycznej aplikacji mówimy, kiedy jesteśmy w stanie obsłużyć szybkie skoki ilości użytkowników, albo operacji w danym momencie. Ale te zmiany nie są stałe, tzn. po krótszej lub dłuższej chwili obciążenie znowu pewnie spadnie, albo jeszcze bardziej się zwiększy. Dobrym przykładem, wspomnianym też w książce, jest system sprzedaży biletów. W długiej perspektywie nie ma on aż tak dużo użytkowników, a na pewnie nie rośnie to szybko i stale w czasie. Ot ilość osób, które albo założyły konto, bo dodają eventy, albo mają konto bo chcą mieć akurat w takiej formie bilet. Jest to na pewno dużo mniejsza ilość niż wynosi ogólna ilość sprzedanych biletów. Jednak są momenty kiedy aplikacja musi na krótką chwilę nagle obsłużyć bardzo duży ruch. Jest to moment otwarcia sprzedaży biletów na jakieś wydarzenie. W takim przypadku mamy duży skok ilości requestów. I nasza architektura, jeżeli jest elastyczna, powinna sobie z tym poradzić – niejako się „rozciągnąć” i przyjąć ten ruch. Potem, kiedy sprzedaż się zamknie, to wracamy do poprzedniego obciążenia.
Nie wszystko od razu
Zostańmy na razie przy przykładzie z poprzedniego paragrafu, czyli przy sprzedaży biletów.
Załóżmy, że składa się on z takich elementów jak:
- Przeglądanie dostępnych miejsc
- Wybór (rezerwacja) biletu
- Płatność
- Wysłanie powiadomień
- Wysłanie biletów
I teraz pytanie do Ciebie: czy mając za zadanie przygotować elastyczny system, który wytrzyma chwilowe obciążenie ruchu związanego z wydarzeniem, musisz być gotowy na tak duży ruch w każdym z tych komponentów?
Absolutnie nie!
Ale wymaga to oczywiście zrozumienia projektu pod względem biznesowym. Bo pierwszą, w miarę oczywistą rzeczą jest to, że wysłanie powiadomień, czy wysłanie biletów prawie na pewno nie muszą się dziać natychmiast. Jeżeli zakolejkujemy ten natłok powiadomień do wysłania, to po prostu ktoś dostanie je po kilkunastu minutach, zamiast w ciągu kilku sekund. Jednak nic złego się pewnie nie stanie.
Ta sama sytuacja jest w przypadku wysyłki biletów. Pomijam tutaj nawet wysyłkę fizycznych biletów, bo w takim przypadku nawet kilka dni opóźnienia nie jest zwykle dużym problemem. Ale musząc wysłać bilety elektroniczne, nie musimy zapewnić, że niezależnie od ruchu system będzie to robił bardzo szybko. „Wirtualna drukarka” biletów może spokojnie mieć zakolejkowane wiele pozycji do wysyłki i nikt się o to nie obrazi. Zwłaszcza jak dodamy w regulaminie, albo wprost na stronie zakupu, że w przypadku dużego zainteresowania bilet może dotrzeć do godziny czasu.
Także te dwa elementy wcale nie muszą być elastyczne, tzn. poświęcanie czasu na ich uelastycznienie nie będzie aż tak wartościowe.
Kolejna od dołu jest płatność. W tym przypadku może się wydawać na pierwszy rzut oka, że to oczywiste, że płatności powinny być elastyczne, w końcu to bardzo ważny krok naszego biznesu!
Tylko tutaj są dwie kwestie:
- Płatności zazwyczaj obsługuje zewnętrzna usługa
- Ilość osób, które jednocześnie będą płacić, jesteśmy w stanie bardzo dokładnie określić i jest ona mocno ograniczona
Jeśli chodzi o pierwszy punkt, to jest on częściowo prawdą. Bo faktycznie, kiedy mówimy o samym procesie płacenia, to zwykle obsługuje to zewnętrzna firma. Więc to oni są odpowiedzialni za dostarczenie elastyczności, ale też dla nich ten formularz płatności jest w zupełnie innym miejscu całej układanki projektowej. Jednak oczywiście nadal po naszej stronie jest przygotowanie przekierowania do strony z płatnością. I nasi klienci będą przez nasz serwer i naszą stronę, np. z podsumowaniem zamówienia, przechodzili.
Ale tutaj dochodzimy do drugiego punktu, czyli tego, że na tym etapie, tak samo jak na wspomnianych wcześniej etapach, mamy skończoną i bardzo dobrze policzalną ilość użytkowników.
Osób płacących nie będzie więcej niż biletów na wydarzenie, także dopóki obsługujemy konkretnej wielkości wydarzenia, to nasza strona z płatnościami nie będzie bardziej oblegana niż ilość miejsc na takie wydarzenie. Tak samo jak nie będziemy wysyłali więcej biletów niż sprzedaliśmy wejściówek. I nawet na największe wydarzenia są to liczby pokroju dziesiątek tysięcy osób. Które w dodatku nie kupują w jednym momencie, bo na tak duże eventy bilety i tak sprzedaje się falami, tak więc równocześnie praktycznie nigdy ani płatności, ani wysyłki biletów nie będą przerabiać więcej niż kilka tysięcy użytkowników.
Zaczyna się zabawa
W końcu dochodzimy do drugiej od góry pozycji, a więc wyboru i rezerwacji miejsca. No i nareszcie zaczynamy być w miejscu, które będzie wymagało elastyczności.
Dlaczego? Bo jest to już miejsce, do którego dostęp nie jest już tak „zamykany” przez ograniczoną dostępność.
Ale jak to? Przecież ilość miejsc jest ograniczona, więc więcej osób, niż jest miejsc, nie można wybrać.
To prawda. Jednak zwróć uwagę, że tutaj już trzeba być świadomym tego, że w przycisk wyboru miejsca będzie klikało więcej osób, niż jest dostępnych miejsc. Zazwyczaj będzie to wyglądało w ten sposób, że kto pierwszy ten lepszy, a kolejni dostaną powiadomienie, że jednak miejsca już nie ma. Jest bardzo duża szansa, że na bardzo oblegane wydarzenie kilka, kilkadziesiąt, albo nawet kilkaset osób praktycznie w jednej sekundzie będzie chciało wybrać to samo miejsce.
Nie będziemy tutaj wchodzili mocno w technikalia i konkretne rozwiązanie, jak można zaimplementować taką rezerwację miejsca. Bo na pewno będą tutaj kwestie związanie z walką o zasoby i jednoznacznym ustaleniem kto był szczęśliwcem, któremu udało się wybrać bilet. Być może dojdzie też kwestia rezerwowania tego biletu na kilka minut, dając czas na przejście całego procesu.
Wspomniany moment wyboru miejsca jest mocno związany z ostatnim, a właściwie pierwszym elementem na naszej liście, czyli przeglądem dostępnych miejsc. Podczas zakupu biletów na event, np. koncert, użytkownicy będą najpierw non stop odświeżali stronę, czekając, aż rozpocznie się sprzedaż. Kiedy tylko to nastąpi, to natychmiast rzucą się na sprawdzanie, której klasy bilety, w jakich sektorach i w jakiej ilości są dostępne. I właśnie wtedy będą natychmiast klikać to co ich interesuje.
I to jest właśnie element, na którym musimy się skupić. Tutaj mamy największą walkę o zasoby. Po przejściu tej linii, w postaci wyboru biletu, mamy już bardzo mocno przefiltrowany ruch. Dlatego wiedząc o tym, powinniśmy większość energii włożyć w elastyczność tej części systemu. To tutaj będzie bardzo agresywne skalowanie, szybki cache, mechanizmy ograniczania ruchu z jednego komputera itp.
Architektura wymaga wiedzy domenowej
Powyższy scenariusz świetnie obrazuje zasada Pareto – 20% systemu, generuje 80% problemów.
Zauważ przy tym, że to co opisałem powyżej ma bardzo konkretną cechę – znajomość domeny.
Przykład z biletami jest bardzo prosty i oczywisty, bo dużo osób miało do czynienia z tym tematem jako klienci. Jednak tego typu problem może się trafić w bardziej niszowych projektach, np. finansowych. Jeżeli nie poznamy procesu od strony biznesowej i nie zrozumiemy jakie zachowania i w jaki sposób będą występować, bo nie wiemy gdzie przyłożyć większość naszej energii.
A zobacz, że jeśli byśmy nie przeanalizowali procesu zakupu biletów i uznali, że duży ruch to duży ruch, więc uelastyczniamy całą aplikację, to zużylibyśmy masę naszej energii na wdrażanie elastycznego skalowania serwisów, albo skomplikowane mechanizmy optymalizujące przepływ, w miejscach, które tego kompletnie nie potrzebują.
I nie tylko nasza praca poszłaby na marne. Zwyczajnie przepalilibyśmy pieniądze, bez konkretnego zysku z tej inwestycji.
Także zawsze kiedy jest mowa o obsłudze dużego chwilowego ruchu pamiętaj:
- Praktycznie nigdy ten wzmożony ruch nie będzie w całej aplikacji, tylko w jej konkretnych częściach. I to na nich powinieneś się skupić
- Żeby odkryć gdzie najprawdopodobniej pojawi się wąskie gardło, musisz zrozumieć domenę biznesową i ściśle współpracować z klientem, który potencjalnie zna, albo przewiduje zachowania swoich użytkowników, pracowników, albo systemów, z którymi będziemy zintegrowani
Leave a Comment