Tanie mikroserwisy z Azure Functions

data: 29 października, 2021
czas czytania: 5 min
autor: Michał Depta

Koszty użytkowania są jednym z najbardziej kontrowersyjnych aspektów wykorzystania chmury obliczeniowej w projektach IT.

O ile duże firmy rzadko traktują chmurę jako metodę optymalizacji kosztów infrastruktury (jeden z wniosków z raportu Cloud FP), to startupy oraz mniejsze przedsiębiorstwa przykładają większą wagę do wydatków i chętnie optymalizują pod ich kątem swoje rozwiązania. Sami programiści są podzieleni w tej kwestii – część nadal uważa, że taniej jest wykorzystywać infrastrukturę on-prem, jednak rosnąca świadomość amortyzowanych kosztów utrzymania własnego Data Center przekonuje coraz większą rzeszę inżynierów do oszczędności płynących z wykorzystania chmury. 

W tym poście pokażę przykłady technik budowania niskokosztowego rozwiązania IT w chmurze Azure z wykorzystaniem modelu serverless. Nie będę omawiał innych aspektów tego podejścia, takich jak np. skalowanie. Treść jest oparta o doświadczenia z projektu komercyjnego realizowanego od 2 lat w FP. 

Tło 

Pracuję wraz z zespołem dla zleceniodawcy o startupowej kulturze organizacyjnej, z oszczędnym podejściem do wydawania pieniędzy na infrastrukturę IT. Oprogramowanie jest tworzone z wykorzystaniem architektury mikroserwisowej. 

Stos technologiczny, którego używamy w projekcie, jest oparty o .NET Core, ale techniki optymalizacji są agnostyczne technologicznie i znajdą również zastosowanie w przypadku chmury AWS. 

Każdy z elementów platformy, którą tworzymy, jest zamknięty w ramach jednej grupy zasobów (Resource Group) Azure, co pozwala nam na dokładne monitorowanie wydatków ponoszonych na utrzymanie infrastruktury każdego mikroserwisu.  

Dalej przedstawię miesięczne podsumowanie wydatków na 2 wybrane Resource Groups. Przykładowe mikroserwisy, którymi posługuję się w tym poście, są rzeczywistymi usługami obsługującymi istotną, choć działającą pod wyraźnie niskim obciążeniem, funkcjonalność naszej platformy. Aktualnie obsługujemy ok. 10 tysięcy aktywnych użytkowników. 

Budowa mikroserwisu 

Azure Functions pozwalają realizować wiele scenariuszy, gdyż funkcja może zostać uruchomiona w reakcji na różne zdarzenia. Budując API wykorzystaliśmy HTTP Trigger, czyli wyzwalanie naszego kodu w celu obsługi żądania HTTP. 

Struktura przykładowego mikroserwisu zbudowanego z usług dostępnych w Azure wygląda u nas następująco: 

Poszczególne elementy pełnią następujące role: 

  • Azure Function – funkcja uruchamia naszą aplikację, która obsługuje żądania klientów, używamy consumption plan, którego cena jest bezpośrednio związana z obciążeniem usługi, 
  • Key Vault – przechowuje poświadczenia i inne elementy konfiguracji, które ze względu na poufność nie mogą się znaleźć w kodzie źródłowym, 
  • Function Storage – jest koniecznym elementem przy wdrażaniu do Azure Functions – po prostu przechowuje kod aplikacji, 
  • Application Insights – używamy tej usługi do monitorowania i raportowania błędów aplikacji, 
  • Data Storage – kontener na dane operacyjne aplikacji. W najprostszej formie może to być np. Storage Table umieszczony w tym samym koncie Azure Storage, co sam kod aplikacji. Usługi bazodanowe, np. Azure SQL czy Cosmos DB, oferują znacznie większe możliwości, ale też podnoszą cenę. Jeden z naszych mikroserwisów pełni rolę fasady na usługę zewnętrznego dostawcy i w ogóle nie posiada własnego źródła danych. 

To ile to kosztuje?

Jak pisałem, śledzimy wydatki na chmurę w granulacji do pojedynczych mikroserwisów, reprezentowanych przez osobne grupy zasobów. Miesięczne koszty takich usług działających aktualnie na produkcji, przy stosunkowo niskim ruchu wynoszą przykładowo: 

  • $0.09 [sic!] dla usługi bez własnego źródła danych – zmienny ruch do 20 żądań na minutę 
  • $1.20 dla usługi przechowującej dane w Azure Storage Table – w miarę jednostajny ruch w granicach do 10 żądań na minutę 

Za co tak naprawdę płacimy? Przy niskim ruchu zużycie mocy obliczeniowej przez funkcje jest dla nas bezpłatne, jedyne koszty, jakie ponosimy, to opłaty za Application Insights (zdecydowanie warte swojej ceny, ale o tym innym razem) oraz Storage. Widać to na poniższych wykresach: 

Czy każdą aplikację da się tak tanio uruchomić? 

Zdecydowanie nie. Celowo posłużyłem się dwoma jaskrawymi przykładami, które w całej krasie demonstrują możliwości optymalizacji kosztowej. Przy większym obciążeniu opłaty za wykorzystaną moc obliczeniową zaczynają rosnąć, a wraz z nimi koszty Application Insights.  

Większość mikroserwisów wymaga często funkcjonalnej bazy danych, z elastyczną możliwością przeszukiwania zawartości. Nawet w najtańszym wariancie oznacza to koszt wysokości od kilku do kilkudziesięciu dolarów miesięcznie. Również w tych przypadkach warto jednak zainteresować się Azure Functions, których cennik zaczyna się od zera, co przy niedużym ruchu pozwala sporo zaoszczędzić.  

Dla porównania, inne nasze mikroserwisy uruchamiane na dedykowanych App Service Plans generują stały miesięczny koszt rzędu kilkudziesięciu dolarów. Biorąc pod uwagę proces rozwoju oprogramowania wykorzystujący dodatkowe środowiska Dev, Test czy UAT, oszczędności na jednym mikroserwisie mogą sięgać kilkuset dolarów miesięcznie. 

Wady 

Istotną (i chyba jedyną, która nas dotknęła) wadą wykorzystania Azure Functions do budowania REST-owych API jest model programowy, który nie pozwala na wygodne wykorzystanie dostępnych narzędzi i bibliotek. Integracja z popularnymi frameworkami wymaga dodatkowej pracy programisty. W przypadku aplikacji .NETowej oznacza to, że trzeba samemu (czyt. własnym kodem) zadbać o część aspektów zrzucanych w OWIN-owym stosie na middleware’y. Podobnie ma się sytuacja w innych technologiach. 

Oczywiście, potencjalnych problemów jest znacznie więcej. Dla przykładu: 

  • ograniczenia wynikające z oferty dostawcy chmury, 
  • potencjalny nagły wzrost kosztów w przypadku błędu designu lub ataku, 
  • zimny start. 

Szczegółowe omówienie tych zagadnień zasługuje na osobnego posta (co najmniej jednego) i być może wrócę do tematu w przyszłości. 

Wnioski 

  1. Optymalizację kosztów uruchomienia aplikacji w chmurze można osiągnąć przez odpowiednie projektowanie i dobór usług.
  2. Warto zastanowić się, czy aplikacja potrzebuje rozbudowanych mechanizmów dostępu do danych. Proste rozwiązania, jak Azure Storage Table czy AWS Dynamo DB pozwalają sporo zaoszczędzić.  
  3. Technologia Serverless umożliwia skalowanie kosztów infrastruktury niemalże od zera i w startupach oraz aplikacjach przewidywanym niskim obciążeniu jest uzasadnionym wyborem. 
  4. Wykorzystanie Azure Functions do budowy REST-owego API wiąże się ze zmianą struktury aplikacji w porównaniu do standardowych .NET Core Web Apps. 

A jakie Wy macie doświadczenia z kosztami w modelu serverless?

Newsletter IT leaks

Dzielimy się inspiracjami i nowinkami z branży IT. Szanujemy Twój czas - obiecujemy nie spamować i wysyłać wiadomości raz na dwa miesiące.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.