Wiedza dedykowana Tobie

Nagły wzrost ruchu na stronie WWW – jak się do niego przygotować?

04 listopada 2015

Organizatorzy akcji medialnych o szerokim zasięgu, a szczególnie tych sezonowych, muszą stanąć czasami przed niemałym wyzwaniem: jak dobrać rozwiązanie hostingowe, które pozwoli na udźwignięcie dużego wzrostu ruchu na stronie WWW w krótkim czasie?

Tego rodzaju sytuacje mają miejsce na przykład podczas kampanii promocyjnych, które emitowane są za pośrednictwem radia i telewizji, czy w trakcie wydarzeń takich jak festiwale filmowe i relacje online z rozgrywek sportowych.

W podobnej sprawie zwróciła się do nas niedawno warszawska Fundacja Centrum Edukacji Obywatelskiej – organizator znanej akcji Latarnik Wyborczy. Na stronie www.latarnikwyborczy.pl fundacja udostępniła aplikację, która umożliwia użytkownikom sprawdzenie zgodności ich poglądów politycznych z programami partii, których przedstawiciele biorą udział w wyborach prezydenckich.

latarnik wyborczy test

Okres przedwyborczy ma jasno wyznaczone ramy czasowe – to właśnie wtedy użytkownicy najczęściej korzystają z Latarnika Wyborczego bezpośrednio z poziomu strony WWW. Jeśli duża grupa osób wykonuje test w tym samym momencie, obciążenie serwera, na którym hostowana jest witryna gwałtownie wzrasta.

To właśnie na wypadek takich sytuacji przeprowadziliśmy na prośbę Fundacji symulację ruchu na stronie www.latarnikwyborczy.pl. Postanowiliśmy zweryfikować, jak będzie kształtowało się obciążenie maszyny w przypadku stale zwiększającej się liczby użytkowników korzystających z aplikacji.

Jak przeprowadza się symulację ruchu na stronie?

Przed wgraniem kopii serwisu na serwer testowy przygotowaliśmy konkretny plan działań:

1. Środowisko aplikacji

W pierwszej kolejności nasi specjaliści przygotowali środowisko aplikacji testujących z wykorzystaniem Erlang i Tsung, aby za ich pomocą przeprowadzić symulację ruchu na stronie. Na podstawie statystyk dotyczących Latarnika Wyborczego podczas zeszłorocznych wyborów do parlamentu europejskiego przyjęliśmy następujące założenia:

  • serwis może być odwiedzany przez 2000 – 8000 użytkowników jednocześnie,
  • co sekundę na stronę wchodzi 150 nowych użytkowników,
  • maksymalny czas, w jakim użytkownicy wypełniają ankietę wynosi 8 minut.

2. Przygotowanie sprzętu

Kolejnym krokiem było wgranie na serwer testowy aplikacji dostarczonej nam przez Klienta. Konfiguracja sprzętowa została przygotowana w taki sposób, aby można było skalować aplikację horyzontalnie i przeprowadzić testy wydajnościowe w różnych wariantach konfiguracyjnych.

3. Symulacja ruchu na stronie

Najważniejszym etapem naszej pracy było przeprowadzanie symulacji ruchu na stronie www.latarnikwyborczy.pl. Symulacja polegała na wygenerowaniu w danym przedziale czasowym (np. przez 30 min) odpowiedniej ilości nowych sesji „odwiedzających” (np. 150 w czasie 1 sekundy).

W przeciwieństwie do zwykłego testu, badającego działanie wywołania jednego konkretnego skryptu (ab, httpref, itp.), testowała ona „realny” ruch na stronie, symulując tym samym najbardziej zbliżone do rzeczywistych warunki pracy całego rozwiązania.

Testy te uwzględniały zarówno czasy przestoju, kiedy odwiedzający czytał treść na stronie, wypełniał ankietę testową,weryfikował swoje wyniki, jak i akcje wykonywane dynamicznie po stronie skryptów np. po wysłaniu instrukcji POST czy otwarciu nowej strony (zapytania do bazy, generowanie dynamicznych stron, itd.).

Każda sesja miała dynamicznie generowane zarówno czasy poszczególnych akcji odwiedzającego (generowane losowo i badane przez testerów realne czasy „thinktime”), jak i dynamicznie generowane odpowiedzi w ramach ankiety.

Napotkane podczas testów słabe punkty aplikacji pozwoliły na rozłożenie całego procesu przeprowadzania symulacji na czynniki pierwsze i dogłębną analizę szczegółów, dzięki czemu audyt aplikacji znacznie nabrał na wartości. Wśród kwestii, na które warto zwrócić szczególną uwagę znalazły się między innymi:

  • konieczność wysyłania odpowiednich nagłówków HTTP z narzędzia testującego, imitując tym samym idealnie ruch taki jak od strony przeglądarki,
  • konieczność modyfikacji generowania sesji po stronie aplikacji – wykryto metodę bazującą na ip + linux timestamp, a co za tym idzie w jednej sekundzie można było przeprowadzić test z jednego adresu IP,
  • weryfikację wyników po stronie bazy danych, gdzie poprawna sesja użytkownika wymagała wykonania szeregu operacji DML (z ang. data manipulation language – język służący do wykonywania operacji na danych takich jak ich zamiana czy usuwanie ich z bazy),
  • znalezienie wąskich gardeł i próby ich optymalizacji,
  • przygotowanie wniosków dla programistów w celu optymalizacji (np. napotkano na nadmiarowe generowanie dynamicznych obrazków, wyciąganie wszystkich rekordów z bazy przy każdym wyświetleniu strony, które później nie są wykorzystywane, itp.)

4. Propozycje rozwiązań

Aby zoptymalizować pracę serwera zaproponowaliśmy Klientowi zastosowanie rozwiązania, jakim jest CDN (z ang. content delivery network, system serwerów rozmieszczonych w kilku centrach danych), którego głównym celem jest zwiększenie poziomu dostępności i wydajności stron internetowych między innymi poprzez cachowanie ruchu statycznego, a dodatkowo ochrona antyDDoS. Jednym z takich systemów jest CloudFlare, którego jesteśmy partnerem.

cloudflare

5. Wybór optymalnej konfiguracji sprzętowej

Uzyskane wyniki testów były dla nas bazą do wyciągnięcia wniosków, na podstawie których zaproponowaliśmy Klientowi końcową konfigurację sprzętową.

Ostatnim etapem testów było ponowne wgranie aplikacji na odpowiednio przygotowany serwer i wykonanie kolejnej symulacji ruchu. Działanie to potwierdziło, że zaproponowane przez nas rozwiązanie jest idealnie skrojone na potrzeby naszego Klienta i zagwarantuje stabilne działanie serwisu przy ustalonej wcześniej wielkości ruchu.

Przymierzając się do tworzenia aplikacji, której zadaniem było zmierzenie się ze znacznym ruchem, utrzymywaniem wielu użytkowników jednocześnie oraz obsługą niezliczonych ilości równorzędnych operacji, spojrzeliśmy na całe zadanie z szerszej perspektywy – z uwzględnieniem systemu wraz z jego architekturą oraz samego kodu.

Zwłaszcza na samym początku warto jest mieć na uwadze fakt, że “strzelanie z armaty do muchy” nie ma większego sensu i należy odpowiednio przygotować aplikację tak, aby można ją było łatwo rozwijać w przyszłości, w szczególności w kontekście aspektów typu skalowalność czy odporność na awarie.

Bardzo ważne jest także to, aby wyjść z biznesowego punktu widzenia i w oparciu o aspekty technologiczne stworzyć wyważony model pracy. Takie podejście pozwoliło nam uniknąć przysłowiowej studni bez dna w kontekście kosztów projektu, a co najważniejsze – nie zaskoczyliśmy naszego Klienta wysokim progiem wejścia w projekt.

Na co warto zwrócić uwagę budując aplikację?

Przy okazji pracy nad powyższym projektem zebraliśmy garść przydatnych informacji i stworzyliśmy przykładowy schemat logiczny architektury, który należy przełożyć na strukturę fizyczną. Na rysunku uwzględniliśmy 4 warstwy elementów i opisaliśmy je dosyć ogólnie, tak aby w przyszłości można było zastosować schemat do innych projektów.

Symulowanie ruchu na stronie

Warstwa nr 1 – Firewall (kolor czerwony)

W każdym rozwiązaniu dobrze jest zabezpieczyć system i tym samym naszą aplikację, np. blokując odpowiednio otwarte porty, filtrując ruch wychodzący oraz przychodzący, a nawet tworząc automaty reguł chroniące aplikację przed potencjalnym zagrożeniem.

Warstwa nr 2 – Load balancing (kolor niebieski)

Na tym etapie odbywa się balansowanie ruchu na wiele logicznych lub fizycznych node-ów. Możliwe jest również dokonywanie wszelkiego rodzaju CACHE-owania. Tego rodzaju działania przede wszystkim odciążają pozostałą część infrastruktury, ponieważ umożliwiają szybkie i sprawne przekazywanie danych do naszej aplikacji. Dzieje się to już na samym początku łańcucha, a wszystko dzięki wykorzystaniu pamięci RAM, co ma uzasadnienie w przypadku contentu statycznego.

Warstwa nr 3 (kolor zielony)

To właśnie w trzeciej warstwie znajdują się elementy serwujące zarówno content statyczny, jak i dynamiczny. Na tym etapie warto zwrócić uwagę na fakt, że aplikacja (czyli content), w związku z tym, że jest skalowalna, powinna być dostępna dla wszystkich node-ów z użyciem dysku, wolumenu czy też zasobu współdzielonego. Inną opcją jest dbanie o aktualizację na wszystkich node-ach lokalnych repozytoriów kodu, ale nie rekomendujemy takiego rozwiązania.

Warstwa nr 4 (kolor żółty)

Ostatnim, ale bardzo istotnym etapem prac jest stworzenie miejsca, w którym można umieścić dodatki niezbędne do prawidłowego działania aplikacji, tzn. silnik baz danych oraz silnik wyszukiwarek.

Dla zwiększenia bezpieczeństwa dostępu do umieszczonych tam komponentów systemu warto zastosować mechanizm proxy do baz danych, który pozwala na wysłanie tylko określonych zapytań od strony frontendu. Nie uwzględniliśmy tego na schemacie, ale dodatkowo można zastosować jeszcze tzw. drugi poziom zapory ogniowej pomiędzy warstwą trzecią (frontend), a czwartą (backend).

Podsumowanie

Efektywnie przeprowadzenie każdych testów obciążeniowych możliwe jest dzięki odpowiednio przygotowanej infrastrukturze i powołanemu zespołowi specjalistów. Istotna jest także dobra komunikacja pomiędzy twórcami oprogramowania po stronie Klientów i zespołem administratorów.

Każdorazowa współpraca w tym zakresie pozwala na optymalizowanie stosowanych procedur i skracanie czasu trwania testów w przyszłości. Do głównych korzyści wynikających z przeprowadzonego audytu można zaliczyć przede wszystkimodkrywanie błędów w aplikacji lub stronie WWW, dzięki czemu można poprawić wydajność projektów Klienta. Podczas przeprowadzania audytu bardzo często udaje się także wykryć luki bezpieczeństwa, których eliminacja pozwala na uniknięcie potencjalnych problemów w przyszłości.

Do tej pory przeprowadzane przez nas symulacje dawały solidną podstawę do dobrania odpowiednich zasobów sprzętowych i optymalizacji kosztów. Mamy nadzieję, że świadomość w zakresie istotności przeprowadzania tego rodzaju testów będzie stale rosła, a nasi administratorzy będą dzięki nim spać spokojniej, zwłaszcza podczas nagłych wzrostów ruchu w serwisach Klientów.