Dzisiejszy temat jest czymś, o czym słyszał niemal każdy, ale prawie nikt nie potrafi wyjaśnić. Serverless. Czym dokładnie jest? Czy to naprawdę tylko kod działający w próżni, czy coś znacznie większego? Wyjaśnijmy sobie jedną rzecz. Serverless nie oznacza braku serwerów. Oznacza, że nie musisz o nich myśleć, a to rozróżnienie zmienia wszystko w sposobie budowania oprogramowania. Pod koniec tego odcinka zrozumiesz, czym właściwie są Azure Functions, jak działa ich cennik i kiedy warto z nich korzystać. Rozbijemy to na elementy pierwsze, zaczynając od największego mitu, co tak naprawdę oznacza serverless. Obalmy od razu kilka mitów. Nazwa serverless to najgorszy termin marketingowy, jaki wymyślił Microsoft. Sprawia, że ludzie myślą, iż serwery w ogóle nie biorą udziału w procesie. To nieprawda. Serwery istnieją, jest ich mnóstwo. Po prostu nigdy nie musisz ich dotykać. 20 lat temu, jeśli chciałeś uruchomić kod w internecie, musiałeś wykonać mnóstwo pracy. Wynajmowałeś maszynę wirtualną, instalowałeś system operacyjny, konfigurowałeś serwer w WU i wdrażałeś aplikację. Potem spędzałeś każdy weekend na poprawkach bezpieczeństwa i upewnianiu się, że całość nie padnie o 3 nad ranem. I w tym rzecz. Płaciłeś za ten serwer, niezależnie od tego, czy twój kod działał, czy nie. Działał w tle, marnując pieniądze, podczas gdy ty spałeś. Serverless wywraca ten model do góry nogami. Piszesz kod, wysyłasz go, a platforma zajmuje się całą resztą. Systemem operacyjnym, łatkami bezpieczeństwa, skalowaniem i dostępnością. Twoim zadaniem jest tylko napisanie istotnej logiki. Pomyśl o tym, jak o różnicy między prowadzeniem kuchni restauracyjnej, a automatem sprzedającym. Kuchnia restauracyjna wymaga pełnej obsługi, stałych dostaw i konserwacji. Kosztuje codziennie, nawet jeśli nikt nie przekroczy progu. Automat w rogu nic nie robi, dopóki ktoś nie naciśnie przycisku. Wtedy budzi się do życia, wykonuje zadanie i znów zasypia. Płacisz za prąd tylko wtedy, gdy rzeczywiście pracuje. Taki właśnie jest serverless w pigułce. Azure Functions to wersja Microsoftu tego rozwiązania. Uruchamia małe fragmenty kodu w odpowiedzi na zdarzenia. Twój kod śpi, dopóki coś go nie wybudzi. Potem działa, kończy pracę i znów zasypia. Jak więc faktycznie wygląda taki kod? Czym są Azure Functions? Funkcja to pojedynczy fragment kodu wykonujący jedno konkretne zadanie. To wszystko. To nie jest cała aplikacja ze stroną logowania, bazą danych i 20 ekranami. To jedno konkretne zadanie. Pomyśl o tym, jak o włączniku światła w domu albo jest wyłączony, albo włączony, gdy pracuje, a potem znowu wyłączony. Tradycyjny serwer www to przeciwieństwo. To jak zostawienie zapalonych świateł w całym domu 24 godziny na dobę, 7 dni w tygodniu, nawet gdy nikogo nie ma w środku. Azure Functions obsługują mnóstwo różnych języków programowania. Możesz użyć tego, w czym czujesz się pewnie, JavaScript, Python, C, Java, PowerShell. Nie ma tutaj jednej poprawnej odpowiedzi. Wybierz język, który już znasz. Teraz wyjaśnijmy pewne powszechne nieporozumienie. Aplikacja funkcji Function App to nie to samo, co funkcja. Aplikacja funkcji jest kontenerem. Pomyśl o niej, jak o skrzynce z narzędziami. Tworzysz jedną aplikację funkcji, a wewnątrz tej skrzynki dodajesz wiele funkcji. Każda funkcja to osobne narzędzie, które wykonuje własne zadanie. Możesz mieć jedną funkcję obsługującą rejestrację użytkowników, drugą przetwarzającą przesłane obrazy, a trzecią wysyłającą nocne raporty. Wszystkie żyją w tej samej skrzynce, ale działają niezależnie. Jeszcze jedna rzecz o funkcjach. Z założenia są bezstanowe. Oznacza to, że nie pamiętają niczego pomiędzy uruchomieniami. Jeśli twoja funkcja przetworzy plik i zakończy działanie, to wszystko. Przy następnym uruchomieniu startuje od zera, nie pamiętając poprzedniego razu. Brzmi to jak ograniczenie, ale w rzeczywistości jest cechą, która czyni je tak potężnymi. Ponieważ funkcje nie przechowują pamięci ani stanu, Azure może błyskawicznie uruchomić stokopii twojej funkcji przy skoku ruchu i równie szybko je zamknąć, gdy ruch spadnie. W ten sposób zyskujesz skalowalność, nie płacąc za bezczynne serwery. Oto pytanie, jeśli funkcja po prostu czeka i nic nie robi, dopóki coś jej nie wybudzi. To co właściwie ją wybudza? Tutaj wkraczają wyzwalacze, triggers. Wyzwalacze, czyli kiedy? Każda funkcja musi mieć dokładnie jeden wyzwalacz i to nie jest opcjonalne. Wyzwalacz to zdarzenie, które wybudza twoją funkcję. Bez niego twój kod po prostu czeka i nie robi zupełnie nic. Pomyśl o wyzwalaczach jak o dzwonku do drzwi. Twoja funkcja jest wewnątrz domu i czeka. Może czekać w nieskończoność. Nic się nie dzieje, dopóki ktoś nie zadzwoni do drzwi. Wtedy funkcja natychmiast reaguje, otwiera drzwi, wykonuje swoją pracę i wraca do czekania. Istnieją cztery wyzwalacze, z którymi początkujący spotykają się najczęściej. Wyzwalacz HTTP to najczęstszy punkt startowy. Ktoś odwiedza adres URL lub wykonuje wywołanie API, a twoja funkcja się uruchamia. W ten sposób budujesz lekkie API bez konfigurowania pełnego serwera www. Jest jeszcze wyzwalacz czasowy, timer trigger, który działa zgodnie z harmonogramem. Ustawiasz wyrażenie cron, na przykład uruchomienie co godzinę lub o pół nocy, a twoja funkcja uruchamia się dokładnie w tych momentach. Idealne rozwiązanie do zadań konserwacyjnych, czyszczenia danych czy generowania nocnych raportów. Wyzwalacz typu blob aktywuje się, gdy plik zostanie przesłany do usługi Azure Storage. Załóżmy, że ktoś przesyła plik PDF do konkretnego folderu. Wyzwalacz blob wykrywa to przesłanie i automatycznie uruchamia twoją funkcję. Jest to niezwykle przydatne przy przetwarzaniu obrazów, konwersji dokumentów i weryfikacji plików. Z kolei wyzwalacz kolejki aktywuje się, gdy w kolejce pojawi się nowa wiadomość. Kolejki pozwalają na odseparowanie różnych części systemu. Jeden serwis umieszcza wiadomość w kolejce, a twoja funkcja ją odbiera i przetwarza, gdy jest gotowa. Zapobiega to blokowaniu całego systemu przez jeden wolno działający serwis. Oto najważniejsza kwestia. Gdy wyzwalacz się aktywuje, automatycznie przekazuje dane do twojej funkcji. Nie musisz ich odpytywać ani sprawdzać, czy coś się wydarzyło. Wyzwalacz dostarcza wszystko, czego potrzebujesz, a twoja funkcja po prostu to przetwarza. Funkcja bez wyzwalacza to tylko kod, który nic nie robi. To właśnie wyzwalacz nadaje jej cel. Wyzwalacz mówi więc twojej funkcji, kiedy ma zostać uruchomiona. Ale skąd pochodzą dane i dokąd trafiają? Tu właśnie wkraczają powiązania bindings. Powiązania, dane wejściowe, dane wyjściowe. Powiązania pozwalają określić, jakie dane funkcja ma czytać i gdzie wysyłać wyniki, bez pisania dodatkowego kodu. Brzmi skomplikowanie, więc uprośćmy to. Istnieją dwa rodzaje. Powiązania wejściowe wprowadzają dane do twojej funkcji. Powiązania wyjściowe wysyłają dane na zewnątrz. Bez nich musiałbyś pisać kod SDK za każdym razem, gdy chcesz połączyć się z kątem magazynu, bazą danych czy kolejką. Musiałbyś obsługiwać parametry połączenia, ponowne próby, serializację danych i deserializację odpowiedzi. To mnóstwo dodatkowego kodu tylko po to, by odczytać plik. Dzięki powiązaniom po prostu deklarujesz, czego potrzebujesz. Mówisz, chcę czytać z tego kontenera blob. Albo chcę pisać do tej kolejki. Środowisko uruchomieniowe zajmuje się resztą. Otwiera połączenie, odczytuje dane i przekazuje je do funkcji jako parametr. Gdy funkcja kończy pracę, bierze wartość zwrotną i zapisuje ją we wskazanym miejscu. Wyobraź sobie powiązania jako rury. Łączysz funkcję z kątem magazynu, bazą danych lub kolejką. Dane płyną tymi rurami automatycznie. Twoja funkcja nie musi wiedzieć, jak te rury działają. Po prostu odbiera to, co przez nie przepływa i wysyła to, co ma wyjść na zewnątrz. Oto konkretny przykład. Załóżmy, że masz powiązanie wejściowe typu blob. Gdy Twoja funkcja się uruchamia, automatycznie odczytuje plik z magazynu blob i przekazuje go jako parametr. Nie musisz pisać żadnego kodu SDK do obsługi magazynu. Po prostu otrzymujesz dane i je przetwarzasz. Inny przykład. Wiązanie wyjściowe kolejki. Twoja funkcja coś przetwarza, a na końcu zwracasz wartość. Środowisko uruchomieniowe przejmuje tę wartość, serializuje ją i umieszcza w kolejce. Nie piszesz żadnego kodu kolejki. Po prostu zwracasz wartość. Wiązania są opcjonalne. Możesz mieć zero, jedno lub wiele. Niektóre funkcje potrzebują tylko wyzwalacza, bez żadnych wiązań. Inne mogą mieć trzy lub cztery wiązania łączące się z różnymi usługami. Połączenie wyzwalaczy i wiązań sprawia, że Azure Functions są tak potężne. Piszesz logikę biznesową, czyli faktyczny kod podejmujący decyzje. Platforma zajmuje się całą integracją. Twoja funkcja pozostaje mała, skoncentrowana i łatwa do zrozumienia. Kwestia cen. Cennik jest tym, co najbardziej zaskakuje początkujących. Dla większości osób plan zużycia Consumption Plan jest domyślnym wyborem i w 90% przypadków powinieneś od niego zacząć. Oto jak to działa. Płacisz tylko wtedy, gdy twoja funkcja rzeczywiście działa. Kiedy jest bezczynna, nic nie płacisz. Zero ani grosza. Na rachunek składają się dwa elementy. Po pierwsze, liczba wykonań, czyli jak często uruchamia się twoja funkcja. Po drugie, czas wykonania, mierzony w tak zwanej. GB sekundach. To w zasadzie czas działania twojej funkcji pomnożony przez ilość użytej pamięci. Darmowy limit jest hojny. Dostajesz 1 milion wykonań miesięcznie i 400 tysięcy gigabajtów w sekund całkowicie za darmo. W przypadku większości małych projektów, aplikacji hobbystycznych i prototypów nigdy nie zapłacisz ani grosza. Nigdy. Jeśli przekroczysz darmowy limit, stawki są nadal niezwykle niskie. 20 centów za milion wykonań. To nie jest błąd w druku. 20 centów za milion uruchomień. Pomyśl o tym, jak opłaceniu za prąd tylko wtedy, gdy włączasz przełącznik. Nie ma miesięcznej opłaty podstawowej za samo posiadanie instalacji elektrycznej w ścianach. Płacisz tylko za energię, którą faktycznie zużyjesz. Istnieją też inne plany. Flex Consumption jest nowszy i zapewnia wsparcie dla sieci wirtualnych. Premium utrzymuje funkcje w gotowości, więc nie ma opóźnienia typu cold start. Dedicated zapewnia stałą wydajność w ramach tradycyjnego planu App Service. Ale na początek plan Consumption jest właściwym wyborem prawie za każdym razem. Jedno ostrzeżenie. Darmowy limit jest współdzielony przez wszystkie twoje aplikacje funkcji w tej samej subskrypcji. Jeśli masz 10 aplikacji funkcji, wszystkie korzystają z tego samego jednego miliona darmowych wykonań. Więc miej na to oko, jeśli zaczniesz tworzyć ich więcej niż kilka. Cennik jest świetny, ale urealnijmy to za pomocą konkretnego przykładu. Scenariusz z prawdziwego życia. Wyobraź sobie, że prowadzisz stronę, na której użytkownicy wgrywają zdjęcia profilowe. Te obrazy są ogromne, mają po 10 megabajtów. A to powoduje kilka realnych problemów. Duże pliki kosztują więcej w przechowywaniu, spowalniają stronę przy ładowaniu i irytują użytkowników, którzy muszą czekać na zdjęcia. Potrzebujesz więc sposobu na automatyczne zmniejszanie tych obrazów. Bez Azure Functions musiałbyś stworzyć pracownika w tle od zera. Oznacza to zdobycie osobnego serwera, konfigurację kolejki zadań i pisanie kodu do obsługi wszystkich elementów. To mnóstwo niepotrzebnej złożoności jak na tak prostą rzecz, jak zmniejszenie obrazu. Dzięki Azure Functions potrzebujesz tylko jednego wyzwalacza typu blob i jednej funkcji. Żadnych serwerów, o które trzeba się martwić. Pozwól, że pokażę Ci, jak to działa. Użytkownik wgrywa zdjęcie na stronę, a plik trafia do pamięci Azure Blob Storage. W momencie pojawienia się pliku automatycznie uruchamia się wyzwalacz typu blob. Twoja funkcja budzi się, wykonuje kod kompresji i zapisuje mniejszą wersję z powrotem w pamięci. Wszystko to dzieje się w ciągu sekund. Użytkownik nigdy nie czeka, ponieważ cały proces odbywa się w tle, całkowicie niewidocznie. Oto kolejny codzienny przykład wysyłanie e-maila powitalnego, gdy ktoś rejestruje się w Twoim serwisie. Wyzwalacz HTTP przechwytuje żądanie rejestracji z Twojej strony. Twoja funkcja uruchamia się, pobiera adres e-mail użytkownika, wysyła wiadomość powitalną przez SendGrid i gotowe. Użytkownik otrzymuje e-mail niemal natychmiast. Żadnego serwera pocztowego, żadnej kolejki wysyłania, tylko jedna funkcja, jedno zadanie, koniec. To dokładnie te zadania, do których zaprojektowano Azure Functions. Małe, skoncentrowane zadania sterowane zdarzeniami. Nie ogromne aplikacje czy złożone procesy, tylko jedna rzecz zrobiona dobrze, wywołana przez coś, co dzieje się gdzie indziej. Kiedy używać Azure Functions? Kiedy więc sięgnąć po funkcje, a kiedy użyć czegoś innego? Oto szybki sposób na decyzję. Zadaj sobie pytanie, czy zadanie jest krótkie, sterowane zdarzeniami i czy jest bezstanowe. Jeśli odpowiedziałeś tak na wszystkie trzy Azure Functions, to prawdopodobnie właściwe narzędzie. Zacznijmy od dobrych przypadków użycia. API i webhooki to idealne dopasowanie. Potrzebujesz lekkiego punktu końcowego, który odpowiada na żądanie HTTP, wykonuje jedną rzecz i zwraca wynik dokładnie do tego stworzono wyzwalacze HTTP. Przetwarzanie plików i obrazów to kolejny ważny przykład. Plik trafia do pamięci, funkcja uruchamia się, przetwarza go i zapisuje wynik, wszystko bez serwera. Zaplanowane zadania, takie jak nocne czyszczenie czy generowanie raportów, świetnie sprawdzają się z wyzwalaczami czasowymi. Transformacja danych w potokach ETL również jest powszechna. Funkcje stanowią doskonałe spoiwo integracyjne, łącząc usługi, które naturalnie ze sobą nie współpracują. Teraz porozmawiajmy o tym, kiedy funkcje nie są dobrym rozwiązaniem. Długotrwałe procesy stanowią problem, ponieważ w planie zużycia funkcje mają domyślny limit czasu 5 minut, który można zwiększyć do 10 po konfiguracji. Jeśli Twoje zadanie trwa dłużej, potrzebujesz czegoś innego. Aplikacje stanowe również do nich nie pasują. Funkcje nie zapamiętują niczego pomiędzy uruchomieniami. Jeśli musisz utrzymać stan sesji lub śledzić postępy między krokami, działasz wbrew ich założeniom. Obciążające zadania obliczeniowe również się nie sprawdzają. Jeśli potrzebujesz stałego użycia procesora przez minuty lub godziny, lepszym wyborem będzie maszyna wirtualna lub kontener. Złożone przepływy pracy, w których jedno zadanie zależy od drugiego, lepiej obsłużą Durable Functions lub Logic Apps. Oto szybki przegląd alternatyw. Azure Logic Apps to opcja no-code służąca do łączenia usług. Jeśli nie musisz pisać własnego kodu, Logic Apps wykona pracę za pomocą wizualnego projektanta. Azure App Service jest przeznaczony dla pełnych aplikacji internetowych działających 24 siódmych. Jeśli potrzebujesz kompletnej witryny lub API, które jest zawsze dostępne, to jest Twoje narzędzie. Azure Container Apps oferuje konteneryzowane mikrousługi z większą kontrolą nad środowiskiem uruchomieniowym. A Azure Virtual Machines daje pełną kontrolę nad systemem operacyjnym, jeśli tego potrzebujesz. Oto prosta zasada. Jeśli potrafisz opisać zadanie w jednym zdaniu, prawdopodobnie jest ono dobrym kandydatem na funkcję. Kompresuj obrazy po ich przesłaniu. Wyślij powitalny e-mail, gdy ktoś się zarejestruje. Uruchamiaj zadanie czyszczenia każdej nocy o północy. Jedno zdanie, jedno zadanie, jedna funkcja. Typowe błędy początkujących, których należy unikać. Teraz porozmawiajmy o kilku rzeczach, na które trzeba uważać. To błędy, które przytrafiają się niemal każdemu na początku. Częstym błędem początkujących jest myślenie, że funkcje są zawsze darmowe. Darmowy limit jest hojny milion wykonań brzmi jak dużo, ale jeśli twoja funkcja stanie się popularna lub zostanie zaatakowana przez bota, te wykonania szybko się sumują. Dlatego monitoruj użycie ustaw alert budżetowy w Azure i unikaj niespodziewanych rachunków pod koniec miesiąca. Innym błędem jest ignorowanie zimnych startów. Pierwsze uruchomienie funkcji po okresie bezczynności trwa dłużej. W planie zużycia może to zająć kilka sekund. W większości przypadków jest to w porządku. Jeśli jednak tworzysz API wrażliwe na opóźnienia, gdzie liczy się każda milisekunda, rozważ plan premium lub włącz zawsze gotowe instancje. Jest jeszcze pisanie funkcji, które działają zbyt długo. Plan zużycia ma limit czasu domyślnie 5 minut, maksymalnie 10 minut. Jeśli twoja funkcja przetwarza plik przez 15 minut, zostanie przerwana w połowie. Podziel to zadanie na mniejsze części lub użyj innego planu hostingu. Kolejnym łatwym do przeoczenia błędem jest brak wdrożenia przez uruchom z pakietu. To prosta zmiana konfiguracji, która poprawia zimny start i zwiększa niezawodność wdrożeń. Zamiast kopiować pojedyncze pliki, wdrażasz spakowany plik zip. Wystarczy zaznaczyć jedno pole w portalu. Zrób to. Wystawianie punktów końcowych HTTP bez uwierzytelniania to kolejna pułapka. Łatwo jest zostawić funkcję jako anonimową podczas testów i zapomnieć ją zabezpieczyć. Ustaw poziom autoryzacji poprawnie od samego początku. Używaj kluczy funkcyjnych lub administracyjnych. Nie zostawiaj otwartych drzwi. Wielokrotne używanie kont magazynu dla wielu aplikacji funkcji to również problem. W środowisku deweloperskim współdzielenie jest w porządku. Na produkcji każda aplikacja funkcji powinna mieć własne konto magazynu. W przeciwnym razie pojawiają się problemy z hałaśliwym sąsiadem, gdzie ruch jednej funkcji spowalnia inne. I wreszcie brak włączenia Application Insights. Bez tego lecisz na ślepo. Nie zobaczysz awarii, błędów ani problemów z wydajnością. Nie dowiesz się, czy funkcja działa za długo lub czy kończy się cichym błędem. Włącz to od pierwszego dnia. Zajmuje to 30 sekund i oszczędza godziny debugowania. Złota zasada tego wszystkiego to utrzymywanie funkcji jako małych, skoncentrowanych i bezstanowych. Jedno zadanie na funkcję, nic więcej. Więc oto cały system. Azure Functions to serverless computing, który uruchamia małe fragmenty kodu w odpowiedzi na zdarzenia. Płacisz tylko wtedy, gdy twój kod jest uruchomiony. Wyzwalacze mówią funkcji, kiedy się obudzić, powiązania łączą ją z potrzebnymi danymi, a plan zużycia sprawia, że jest niemal darmowa dla małych projektów. Twoim najlepszym krokiem teraz jest utworzenie prostej funkcji wyzwalanej przez HTTP w portalu Azure. Zajmuje to 5 minut i nic nie kosztuje. Zasubskrybuj Microsoft Knowledge Nugget, aby otrzymywać więcej wyjaśnień prostym językiem i udostępnij to komuś, kto ciągle pyta, co oznacza serverless. Frau.