Dlaczego ASP.NET na VPS Windows w nazwa.pl jest szybszy?
Jestem aktualnie na etapie budowania własnej aplikacji opartej o platformę .NET. Pierwsi użytkownicy być może zjawią się już niedługo. Nie chciałbym ich zawieść poziomem usług, które będę udostępniał, a na niego ma wpływ nie tylko to, co i jak przygotuję, ale też to, gdzie moja aplikacja będzie uruchomiona. W końcu nic tak nie frustruje, jak długie oczekiwanie na załadowanie się treści albo regularny brak dostępu do usługi.
I akurat w tym samym momencie odezwała się do mnie firma nazwa.pl, która oferuje serwery VPS właśnie na takie okazje.
Spółka nazwa.pl na pewno jest znana większości z Was. Oferuje szeroko rozumiane usługi związane z hostingiem i właśnie we współpracy z nią odpowiem na pytanie: co sprawia, że ASP.NET na VPS-ie z Windowsem w nazwa.pl jest szybszy?
Zastanawiając się nad odpowiedzią, przeszukałem Internet w celu znalezienia informacji na temat wydajności aplikacji w ASP.NET. Zerknąłem też na ofertę konkurencji, w tym na ofertę od samego Microsoftu, czyli usługi Azure. Pytałem również osoby znające platformę .NET na wylot.
Plan, który wybrałem w nazwa.pl jako referencję do porównań nazywa się „VPS Speed Biznes”. Jest to VPS zoptymalizowany pod Windowsa, z 2 rdzeniami procesora taktowanego zegarem 3,3 GHz (chociaż jak widać na poniższym zrzucie ekranu spokojnie działał on z wyższą prędkością, nawet do 3,7 GHz), 4 GB pamięci RAM i 50 GB powierzchni dyskowej.
I właśnie na CPU się tutaj przede wszystkim skupię, bo jest to element, który na pewno wyróżnia ofertę nazwa.pl, a jednocześnie, co za moment udowodnię, jest to też rzecz, która realnie wpływa na wydajność działania naszej aplikacji.
Czym jest VPS
Zanim jednak przejdę do odpowiadania na główne pytanie, to warto żebym odniósł się najpierw do kwestii: czym jest VPS? Mimo, że nie jest to nowe pojęcie (jest z nami od naprawdę wielu lat), to dla części z Was może ono nie być jasne, a jego znajomość pozwoli lepiej zrozumieć dalszą część tekstu.
W dużym skrócie VPS, czyli Virtual Private Server, jest czymś pomiędzy współdzielonym hostingiem, a całkowicie osobną maszyną, do której mamy bezpośredni dostęp przez sieć i jest dla nas dostępna na wyłączność.
W przypadku hostingu współdzielonego nasza aplikacja jest po prostu uruchamiana obok innych aplikacji w jednym środowisku. Można to porównać do sytuacji, kiedy na naszym komputerze otworzylibyśmy bardzo dużo różnego typu programów. Każdy z nich ma teoretycznie dostęp do wszystkich zasobów (jak procesor czy pamięć RAM), ale jeśli któryś z nich zacznie zabierać tych zasobów więcej, to reszta zaczyna działać coraz wolniej.
Bolączki hostingu tradycyjnego przezwycięża CloudHosting, który w Polsce oferuje tylko nazwa.pl. Jest on oparty na technologii chmury obliczeniowej. Nie wykorzystuje pojedynczej maszyny, lecz całe klastry serwerów, zapewniając odpowiednią moc do działania dynamicznych serwisów WWW i aplikacji. W momencie, gdy dojdzie do zwiększenia obciążania, specjalistyczne mechanizmy, zwane load balancerami, błyskawicznie przekierowują ruch na najmniej obciążone serwery w klastrze. Tym samym CloudHosting oferuje nam moc setek maszyn, a nie pojedynczego urządzenia, jak w przypadku tradycyjnego hostingu. Pomimo uniwersalności i licznych zalet, CloudHosting nie pozwala uzyskać pełnej kontroli nad maszyną (dostęp root w Linuxie lub uprawnienia Administratora w Windowsie) i w przypadku potrzeby, np. uruchomienia własnego oprogramowania systemowego, potrzebujemy czegoś więcej.
Serwer dedykowany oferuje wyższy poziom możliwości i zapewnia całkowitą kontrolę. Możemy sobie to wyobrazić jako kupowanie nowego komputera dla każdego programu, jaki chcemy mieć uruchomiony. Właściwie nie jest to aż tak dalekie od rzeczywistości, bo serwer dedykowany, to po prostu cała maszyna, do której tylko my mamy dostęp i tylko nasze aplikacje będą tam uruchamiane.
W końcu mamy też głównego bohatera tego tekstu, czyli serwer VPS. Bierze on elementy z wyżej wymienionych rozwiązań i jest rozsądnym kompromisem, jeżeli nie potrzebujemy całkowitej kontroli nad maszyną i instalowanym systemem. Warto jednak podkreślić, że nazwa.pl daje do wyboru wiele wersji serwerowych Windows i Linux. Nie mamy tutaj problemu podbierania sobie nawzajem zasobów przez aplikacje wielu klientów, który występuje w hostingu współdzielonym, ponieważ w przypadku VPS-a zasoby takie, jak RAM czy CPU, są do naszej wyłącznej dyspozycji. Jest tak dlatego, że VPS korzysta z dobrodziejstw wirtualizacji. Oznacza to, że dostajemy dostęp do maszyny wirtualnej, a tym samym do części zasobów fizycznego serwera. Więc w dużym uproszczeniu można to sobie wyobrazić tak, że jeżeli serwer ma 8 rdzeni i 32 GB RAM, to możemy na nim uruchomić 4 wirtualne serwery i każdy z nich będzie miał swoje 2 rdzenie i swoje 4 GB RAM-u i żaden inny wirtualny serwer mu tego nie zabierze. Nie ma też tutaj problemów występujących przy serwerach dedykowanych, jakimi są: zdecydowanie wyższa cena i konieczność precyzyjnego określenia wymagań, jak i wnikliwej znajomości systemu. Jeżeli dostajemy całą maszynę, to zmiana jej parametrów wiąże się ze zmianą fizycznych komponentów, które zawiera.
Elementy aplikacji ASP.NET
W ramach tego tekstu zakładam, że mamy do czynienia z przeciętną aplikacją w ASP.NET, która łączy się z bazą MS SQL Server za pomocą Entity Frameworka, posiada jakąś bardziej złożoną logikę, obsługuje konta użytkowników i udostępnia dane w postaci API, a uwierzytelnianie i autoryzacja wykorzystują token JWT.
Dlaczego przyjąłem takie założenia? Odpowiedź jest prosta: aplikacje SPA ciągle zyskują na popularności, a dla nich potrzeba danych w formacie JSON, zaś sama część frontendowa jest trzymana zazwyczaj jako statyczne pliki, a do tego korzysta z CDN-ów. Obsługa użytkowników to bardzo powszechna sprawa, a połączenie Entity Frameworka i MS SQL Servera jest podstawowym wyborem, jeżeli chodzi o aplikacje pisane w ASP.NET.
Sprawny CPU
Serwer VPS tak, jak większość typowych serwerów przygotowanych pod kątem hostingu, posiada kilka gigabajtów pamięci RAM. Sprawia to, że dbanie o porządek w pamięci jest istotne, tym bardziej, jeżeli chcemy ją wykorzystać jako pamięć podręczną (cache) dla powtarzających się operacji.
W takim wypadku .NET będzie na pewno intensywnie korzystał z mechanizmu Garbage Collection. Operacje, jakie się z tym wiążą, zdecydowanie powinny trwać jak najkrócej. W końcu jest to moment, kiedy .NET zatrzymuje działanie naszego kodu, aby posprzątać niepotrzebne obiekty. Co pozwala przyspieszyć tę operację, a przez to pozwolić też działać naszej aplikacji z najkrótszymi możliwymi przerwami? Jest to procesor! Im jest szybszy, tym szybciej zakończy się każdy proces czyszczenia pamięci. Możemy więc śmiało powiedzieć, że szybkość procesora ma bezpośredni wpływ na pracę naszej aplikacji, a procesory dostępne w usłudze VPS od nazwa.pl są o około 40% szybsze od procesorów dostępnych u konkurencyjnych dostawców.
Nie bez powodu opisując aplikację zwróciłem uwagę na fakt, że nie tylko obsługuje ona użytkowników, ale korzysta również z tokenów JWT. Zrobiłem to, ponieważ oba te elementy łączy kolejny temat, jakim jest korzystanie z algorytmów do szyfrowania bądź hashowania danych. Procesory Intel, znajdujące się w VPS-ach nazwa.pl, tylko czekają na takie zadania. Z każdą kolejną generacją Intel podnosi wydajność sprzętowego szyfrowania danych. Jeżeli połączymy to z wysokim taktowaniem procesorów dostępnych w nazwa.pl, to dostaniemy świetne maszyny do takich operacji.
Nie można w tym miejscu pominąć tematu serializacji i deserializacji do formatu JSON. Jest to kolejny często powtarzany proces, tym częstszy, im bardziej dynamiczna jest nasza aplikacja. Jednocześnie jest to też proces, który wpływa na wykorzystanie CPU i pamięci RAM, m.in. przez wpływ na ilość pracy dla Garbage Collectora.
To, co powyżej opisałem, to głównie elementy związane z pracą samego frameworka .NET, a przecież nasze aplikacje wykonują jeszcze mniej lub więcej wszelkiej maści operacji, takich jak obliczenia! Każda z nich to kolejny czynnik wpływający na obciążenie procesora. Więc im szybszy procesor, tym szybciej wszystkie te operacje mogą być zakończone, a więc prędzej aplikacja może przejść do obsługi następnych użytkowników.
Skala robi różnicę
Choć w przypadku pojedynczej operacji, czy też jednego użytkownika to, co przed momentem opisałem, będzie Ci się wydawać niezauważalne, to pamiętajmy, że aplikacje webowe są systemami, z których z założenia korzysta wielu użytkowników jednocześnie. W takim przypadku każda kolejna czynność, którą wykonują, jest powtarzana dziesiątki, setki albo i tysiące razy w krótkich odstępach czasu.
Mogłoby się wydawać, że przecież wygenerowanie lub sprawdzenie tokena albo serializacja obiektu do formatu JSON to ułamek sekundy. Jeżeli jednak te ułamki sekundy pomnożymy przez rosnącą liczbę użytkowników, to okaże się, że dostajemy zauważalne wartości. Zwłaszcza w przypadku aplikacji, które są intensywnie wykorzystywane, chociażby w czasie dnia pracy. Pamiętajmy, że nowy token zwykle generuje się co kilka minut, a sprawdza się go zdecydowanie częściej, nie mówiąc już o zamianie danych między obiektami i formatem JSON, która w przypadku API jest wykonywana praktycznie non stop.
Poza tym, jeżeli w naszym kodzie staramy się pracować z podejściem zwanym „obiekty niezmienne”, to dążymy do tego, żeby takich obiektów było dużo, a przez to często będą one usuwane z pomocą Garbage Collectora. Podobnie jest w sytuacji, kiedy po prostu tworzymy przede wszystkim obiekty lokalne w dużej liczbie niewielkich funkcji. Jeżeli dodamy do tego drugą skrajność, czyli wykorzystanie mechanizmu cache, który powoduje, że duże porcje danych są trzymane chociażby przez kilka minut, a potem w jednym momencie usuwane i zastępowane nowymi, to dajemy Garbage Collectorowi, dostępnemu w .NET, naprawdę dużo pracy, która jak najbardziej jest potrzebna, ale jednocześnie czasochłonna. Dlatego możliwość skrócenia jej chociażby przez skorzystanie z szybszego procesora, który zwyczajnie pozwoli takie zadania „odśmiecenia” pamięci wykonać szybciej, daje nam większą swobodę w podejściu do tworzenia aplikacji.
Dane natychmiast
Nie bez znaczenia pozostaje także dysk twardy. Nawet jeżeli ciężkie pliki, które zmieniają się rzadko, będą prawdopodobnie i tak trzymane w pamięci cache przeglądarki użytkownika, tak dane różnego typu muszą być dostępne maksymalnie szybko, zwłaszcza jeżeli często je przeszukujemy. W momencie, kiedy będzie ich więcej niż mamy dostępnej przestrzeni w pamięci RAM, silnik bazy danych nie będzie miał wyboru i będzie wczytywał dane dużo częściej bezpośrednio z dysku. W takim wypadku wydajność dysku znacząco wpływa na to, jak długo potrwa operacja przeszukiwania naszej bazy danych. Na szczęście VPS-y w nazwa.pl są wyposażone w wydajne dyski NVMe, połączone dodatkowo w macierz RAID10, a więc taką, która nie tylko gwarantuje większe bezpieczeństwo danych, ale też jeszcze bardziej zwiększa wydajność i tak już szybkich dysków SSD.
Poza tym szybkość dysków NVMe pozwala rozsądnie podejść do przechowywania danych w pamięci RAM. Dzięki temu, że operacje odczytu są krótkie, to nie musimy każdej informacji przechowywać w pamięci jak najdłużej, a w konsekwencji pamięć RAM może być dostępna w rozsądnych ilościach także w innych obszarach i zadaniach naszej aplikacji.
Jednak w przypadku dostępu do danych, które mamy w bazie, po raz kolejny nie możemy też zapomnieć o wykorzystaniu procesora. Silnik bazodanowy, którego użyjemy w aplikacji, to kolejny element, który chętnie skorzysta z szybkiego CPU. I takie właśnie szybkie CPU zapewnia VPS w nazwa.pl.
Podsumowanie
Jak widać, dostęp do szybszego CPU i dysków wykorzystujących najwydajniejsze interfejsy jest czymś, co pozwala nam realnie wpłynąć na szybkość działania naszej aplikacji. Ponieważ wśród sprawdzonych przeze mnie ofert tylko nazwa.pl ma taką, która zawiera procesor taktowany zegarem aż 3,3 GHz, to zdecydowanie mogę powiedzieć, że jest to oferta, która pozwala uzyskiwać w naszych aplikacjach pisanych z użyciem ASP.NET lepsze wyniki, jeżeli chodzi o wydajność i zużycie zasobów. Jest to tym bardziej istotne, że VPS-y z racji swojej specyfiki nie są wyposażane w bardzo dużą liczbę rdzeni albo wręcz w platformy wieloprocesorowe. W takim przypadku fakt, że jakaś operacja zakończy się nawet 40% szybciej, jest tym bardziej na wagę złota. Każdy rdzeń jest cenny i jego szybsza gotowość na kolejne operacje daje nam szanse na obsłużenie większej liczby klientów i zaserwowanie im naszych treści i usług jeszcze sprawniej, jednocześnie utrzymując na rozsądnym poziomie koszty prowadzenia naszej działalności.
Leave a Comment