Poniżej moje własne oraz zebrane z innych źródeł najlepsze praktyki dotyczące projektowania i programowania funkcji Lambda. Pomijając aspekty bezpieczeństwa praktycznie wszystkie pozostałe wpisują się w pryncypium architektonicznie: funkcja lambda powinna działać jak najkrócej.
Najlepsze praktyki dotyczące AWS Lambda
Funkcja Lambda jest bezstanowa i w taki sposób powinna zostać zaprogramowana.
Stan powinien być przechowywany poza funkcją. Najlepiej w innej usłudze serverless np. S3 lub DynamoDB. Mogą to też być innego typu bazy danych, w tym relacyjne (AWS RDS), przy czym należy pamiętać o niskiej skalowalności takich baz w porównaniu z Lambdą.
Odseparuj logikę funkcji od metody wywoływanej przez AWS (zwyczajowo nazywanej
handler
). W ten sposób łatwiej Ci będzie testować logikę biznesową funkcji oraz zmigrować się na inną chmurę publiczną jeśli zajdzie taka potrzeba.Ponownie wykorzystuj istniejące zasoby. Utrzymuj połączenia do bazy w ciepłych funkcjach - jest duża szansa, że będziesz mógł je użyć przy kolejnym wywołaniu funkcji, co oszczędzi czas potrzebny na ponowne nawiązanie połączenia.
Gdzie to możliwe korzystaj ze zmiennych statycznych, globalnych oraz wzorca singleton. Dzięki czemu przy kolejnych wywołaniach ciepłej funkcji nie będziesz tracił czasu na ponowną inicjalizację obiektów lub zmiennych.
Korzystaj ze zmiennych środowiskowych, aby automatycznie konfigurować zmienne np. ARN kolejki, czy nazwa wiaderka S3.
Korzystaj z SSM Parameters i Secrets Manager. Nigdy nie umieszczaj kluczy, haseł i innych sekretów w kodzie.
Minimalizuj wielkość kodu funkcji. W Java czy JavaScript zależności do bibliotek i frameworków szybko mogą przekroczyć dziesiątki a nawet setkę megabajtów. Kontroluj swoje zależności, aby zminimalizować wielkość deploymentu i oszczędzić na czasie (oczekiwania programisty i uruchamiania się funkcji).
Loguj wywołania funkcji do CloudWach Logs. Używaj filtrów, metryk i alarmów w CloudWatch w celu lepszego monitoringu wdrożonego systemu serverless.
Używaj warstw gdy chcesz uruchomić lokalnie z poziomu funkcji własną komendę/binarkę linuxową. (Przykładowo w warstwie możesz dostarczyć do kontenera Lambda aplikację
ffmpeg
do edycji audio i wideo. Dzięki czemu za każdym razem gdy będziesz aktualizować kod funkcji Lambda nie będziesz musiał wysyłać wraz z kodem binarkiffmpeg
).Warstwy możesz wykorzystać do standaryzacji rozwiązań powtarzalnych problemów (nie wiem jak jest po polsku cross-cutting concern 🙂 ), gdyż jedną warstwę możesz umieścić w dowolnej liczbie funkcji.
Dobierz odpowiednio ilość pamięci do funkcji. Im więcej RAMu przydzielone tym droższe wywołanie, ale paradoksalnie funkcja może generować mniejsze (podobne) koszty, niż ten sam kod wywołany na 128 MB, ponieważ wykona się znacznie szybciej.
Jeśli zależ Ci na szybkość działania ale również wygodzie developmentu to rozważ JavaScript zamiast innego języka. Nie wybieraj Go tylko dlatego, że w testach jest najszybsze. Już kilkukrotnie słyszałem negatywne opinie na temat tego języka od osób, które się na niego przesiadły. Więcej na ten temat w moim poradniku 12 rzeczy o Serverless, które musisz wiedzieć przed rozpoczęciem projektu w chmurze AWS.
Waliduj dane wejściowe. Obsługuj wyjątki i błędy.
Zarządzaj timeoutami do zewnętrznych zasobów. Chyba nie chcesz aby Twoja funkcja bezczynnie czekała na brak odpowiedzi z jakiegoś zasobu. W końcu płacisz za ten czas.
Nie używaj rekurencji (nie wywołuj funkcji samą sobą).
Wbrew oczekiwaniom Twoja Lambda może się wywołać więc razy niż raz na pojedyncze żądanie. Jest to związane z obsługą błędów w usłudze Lambda ale również np. z brzegowymi sytuacjami w kolejkach których używasz. Bez różnicy na powód Twoja funkcja powinna być idempotentna, czyli powinna sobie poradzić w wielokrotnym wywołaniem z tymi samymi parametrami lub żądaniem. Więcej info tutaj.
Najlepsze praktyki dotyczące AWS Lambda w VPC
Unikaj umieszczania funkcji lambda wewnątrz VPC.
Jeśli już musisz mieć funkcję wewnątrz VPC to unikaj używania DNSów do ‘resolvowania’ domeny, gdyż może to zająć dodatkowe kilka sekund.
Zdefiniuj przynajmniej po jednym subnecie na strefę dostępności (availability zone) swojej funkcji.
Każda działająca instancja funkcji w VPC otrzymuje IP. Upewnij się, że w przypadku dużej ilości wywołań funkcji naraz nie przekroczysz zdefiniowanych limitów (zawsze możesz je zwiększyć).
Powyższe najlepsze praktyki zebrałem na bazie swoich doświadczeń oraz wiedzy zebranej w poniższych książkach:
- AWS Certified Developer - Associate Guide: Your one-stop solution to passing the AWS developer’s certification
- DevOps for Serverless Applications: Design, deploy, and monitor your serverless applications using DevOps practices