Poniższy artykuł to część serii poświęconej zwiększaniu wydajności baz danych w Technologii Ruby on Rails. Skupiam się tu na omówieniu cache stron. Jeśli interesuje Cię przyśpieszenie aplikacji, sugeruję przeczytać od początku :). Aplikacja opisywana poniżej jest dostępna na Githubie wraz z wynikami badań.

Jakiś czas temu opisałem jak uniknąć problemu n+1 w aplikacjach Ruby on Rails oraz jak wpływa to na wydajność aplikacji internetowych. Kolejnym sposobem przyśpieszenia odpowiedzi na zapytanie przeglądarki jest umiejętnie wykorzystanie cache’owania akcji kontrolerów, poszczególnych elementów widoku albo całych stron.

Cache całych stron

Cache’owanie całych stron w Ruby on Rails polega na wygenerowaniu przez framework tymczasowego pliku HTML, którego obecność serwer WWW sprawdza, zanim w ogóle dotknie stosu Ruby on Rails, co oczywiście jest bardzo szybkie.

Załóżmy, że przyśpieszana aplikacja posiada na ładowanej stronie wiele metod angażujących serwer obliczeniowo, na przykład wyświetlenie dużej ilości danych statystycznych.

Dla każdego obiektu należy wtedy wywołać metody obliczające, na przykład ilość wyświetleń, ilość ocen, ilość komentarzy autora oceny, wyciągnięcie z tego wartości obliczonej, następnie wygenerować dokument HTML, wstawiając w odpowiednie miejsca wszystkie obliczone dane, a na koniec wyświetlić go w przeglądarce. Jeżeli obliczenia zajmą dwie sekundy, do całkowitego czasu ładowania witryny dodawany jest czas obliczeń, co może znacząco spowolnić stronę.

Niemniej, nawet jeśli obliczeń nie ma na stronie dużo, a aplikacja ma za zadanie wyświetlić statyczną stronę główną, która z zasady zmienia się bardzo rzadko, do zaprezentowania jej zupełnie nie potrzeba frameworka Ruby on Rails, który zanim dostarczy kompletny dokument przeglądarce, angażuje kilka warstw oprogramowania.

W przypadku wykorzystanie techniki cache’owania stron, przy pierwszym zapytaniu do serwera proces ładowania witryny jest taki sam, to jest framework Ruby on Rails kompiluje kompletny dokument HTML i wykonuje wszystkie obliczenia by wypełnić go poprawnie treścią. Różnica jest taka, że oprócz wysłania dokumentu przeglądarce, zapisuje go w publicznym katalogu.

Przy odświeżeniu tej samej strony ponownie, już wcześniej wygenerowany dokument jest pobierany z serwera, dzięki czemu odchodzi nam czas obliczania zmiennych, zapytań do bazy w celu pobrania danych oraz kompilowania dokumentu.

Odchodzi także czas potrzebny na przejście przez stos Ruby on Rails w celu obsługi zapytania z przeglądarki, dzięki czemu odciążony serwer może obsłużyć większą ilość ruchu na stronie.

W celu zobrazowania przykładu napisałem aplikację wyświetlającą 10 obiektów, dla każdego wyświetlając sumę elementów milion-elementowej tablicy, by pokazać różnicę w ładowaniu statycznej strony przy użyciu metody cache’owania.

Na dwóch rysunkach poniżej widać, jak bardzo przyśpieszony został proces dostarczenia dokumentu do przeglądarki na stronie wykonującej czasochłonne obliczenia.

Wykres odpowiedzi serwera brak cache stron

Histogram czasu odpowiedzi serwera bez użycia mechanizmu cache’owania stron.

Odpowiedzi serwera po użyciu cache stron

Histogram czasu odpowiedzi serwera z użyciem mechanizmu cache’owania stron.

Testowana aplikacja dziesięciokrotnie wykonywała kod:

Dzięki wykorzystaniu mechanizmu cache’owania stron, powyższe obliczenia nie zostawały powtarzane, a aplikacja Ruby on Rails nie została w ogóle zaangażowana przy obsłudze zapytania. Pozwoliło to na przyśpieszenie strony dwudziestokrotnie oraz całkowite odciążenie serwera od obsługi zapytania dla danego adresu url.

Jak wykorzystać cache stron w Ruby on Rails

Do wykorzystania cache całych stron w Ruby on Rails należy użyć gemu actionpack-page_caching , który został wyodrębniony z rdzenia Ruby on Rails, gdyż framework ten jest dedykowany do dostarczania dynamicznej, nie statycznej treści. W listingach poniżej przedstawiłem sposób zaimplementowania cache’owania stron w Ruby on Rails.

Cache akcji kontrolerów

W przypadku, gdy jakikolwiek element na stronie może ulec zmianie przy każdym zapytaniu, cache całych stron nie jest dobrym rozwiązaniem. Jeśli jednak jedyną zmianę, którą należy wprowadzić, to wykonanie jakichś metod przed akcją kontrolera, jak na przykład filtrowanie obiektów, można wykorzystać drugą metodę cache’owania w Ruby on Rails, to jest cache akcji kontrolerów.

Wyniki czasu odpowiedzi dla funkcji sumującej tablicę powyżej są bardzo podobne dla obu metod cache’owania, widoki nadal ładowane są ze statycznych dokumentów HTML, przez co nie są wykonywane zawarte w nich czasochłonne funkcje obliczeniowe, z tą różnicą, że uruchamiane są kontrolery aplikacji, by serwować odpowiednie pliki HTML dla przeglądarki.

Odciążenie serwera jest w tym wypadku mniejsze, lecz nadal jest on zwolniony z potrzeby kompilowania dokumentu HTML przy każdym zapytaniu ze strony użytkownika.

Cache fragmentów kodu

Cache fragmentów witryny to trzecia metoda wykorzystania cache po stronie serwera w Ruby on Rails. Pozwala na zapisanie części renderowanej strony na serwerze i pobranie jej bez konieczności obliczania jej zawartości ponownie.

W tym trzecim wypadku różnica w różnica w renderowaniu jest najmniejsza, w porównaniu do cache akcji kontrolerów oraz cache całych stron, gdyż Ruby on Rails jest w pełni angażowany i uruchamiane są wszystkie warstwy aplikacji, łącznie z kompilacją widoków.

Dla naszego przykładu sumowania tablicy ta metoda także byłaby odpowiednia, funkcja wykonująca sumowanie elementów dużej tablicy najbardziej angażująca serwer metoda także nie zostałaby wykonana przy kolejnych zapytaniach.

Implementacja cache fragmentu kodu w Ruby on Rails.

Podsumowanie

Wynik eksperymentu jest dość oczywisty i jak najbardziej oczekiwany. Ładowanie statycznego dokumentu pozwala uniknąć wykonywania jakichkolwiek obliczeń, co w oczywisty sposób przyśpiesza witrynę niemniej mechanizm ten przydaje się wyłącznie w stronach ze statyczną treścią, takich jak strony główne aplikacji, na które kierowany jest cały zdobywany ruch, albo strony z wpisami na blogach.

Umiejętnie wykorzystany pozwala jednak na wielokrotne przyśpieszenie ładowania witryny oraz odciążenie serwera, czyli na redukcję kosztów utrzymania aplikacji, a także na wzrost zadowolenia internautów wchodzących na badaną witrynę.

Pin It on Pinterest

Share This
Sekrety Produktywności

Sekrety Produktywności

DARMOWE szkolenie mailingowe! 10 porad jak zwiększyć produktywność w programowaniu.

Dziękujemy za zapisanie się na kurs. Wkrótce otrzymasz wiadomość email z potwierdzeniem zapisu.

FreshMail.pl