Сьогоднішня тема – це те, про що майже всі чули, але майже ніхто не може пояснити. Серверлес. Що це таке насправді? Чи це справді просто код, що працює ніде, чи щось значно більше? Давайте з'ясуємо дещо одразу. Серверлес не означає відсутність серверів. Це означає, що ви про них не думаєте, і ця відмінність змінює все у створенні програмного забезпечення. До кінця цього епізоду ви зрозумієте, що таке Azure Functions, як працює ціноутворення і коли їх варто використовувати. Ми розберемо це на складові, почавши з найбільшого міфу, що насправді означає серверлес. Давайте відразу розвіємо кілька міфів. Назва серверлес – це найгірший маркетинговий термін, який будь-коли вигадував Майкрософт. Він змушує людей думати, що жодних серверів взагалі не існує. Це неправда. Сервери є, і їх дуже багато. Просто вам ніколи не доводиться з ними взаємодіяти. 20 років тому, якщо ви хотіли запустити код в інтернеті, вам доводилося багато працювати. Ви орендували віртуальну машину, встановлювали ОС, налаштовували веб-сервер і розгортали програму. Потім кожній вихідні ви витрачали на встановлення патчів безпеки та перевірку, чи не впало все о третій годині ночі. І ось у чому річ. Ви платили за той сервер незалежно від того, чи працював ваш код. Він просто гудів і спалював гроші, поки ви спали. Серверлес перевертає цю модель з ніг на голову. Ви пишете код, завантажуєте його, а платформа бере на себе все інше. Операційну систему, патчі безпеки, масштабування та доступність Ваша робота – лише написати важливу для бізнесу логіку. Уявіть це як різницю між роботою ресторанної кухні та торговим автоматом. Ресторанна кухня потребує персоналу, постійних запасів продуктів та обслуговування. Вона коштує грошей щодня, навіть якщо жоден клієнт не зайшов у двері. Торговий автомат просто стоїть у кутку, нічого не роблячи, поки хтось не натисне кнопку. Тоді він оживає, виконує свою роботу і знову засинає. Ви платите за електрику лише тоді, коли він реально працює. Це і є сервер-лес у стислому вигляді. Azure Functions – це версія такого підходу від Microsoft. Вона запускає невеликі фрагменти коду у відповідь на події. Ваш код перебуває в режимі сну, доки щось його не розбудить, потім він виконується, завершується і знову засинає. Отже, як насправді виглядає цей код? Що таке Azure Functions? Функція – це окремий фрагмент коду, що виконує одне конкретне завдання. Це все. Це не ціла програма зі сторінкою логіну, базою даних і 20 екранами. Це одне ціле спрямоване завдання. Уявіться, як вимикач світла у вашому домі або вимкнено, або увімкнено, коли виконується робота, а потім знову вимкнено. Традиційний веб-сервер – це протилежність, як залишити світло в усьому домі увімкненим 24 години на добу, 7 днів на тиждень, навіть коли нікого немає вдома. Azure Functions підтримує багато різних мов програмування. Ви можете використовувати те, що вам зручно – JavaScript, Python, C, Java, PowerShell. Тут немає єдиної правильної відповіді. Обирайте ту мову, яку ви вже знаєте. Тепер розберімося з поширеною плутаниною. Function App – це не те саме, що функція. Function App – це контейнер. Уявіть, це як ящик для інструментів. Ви створюєте один Function App і додаєте в цей ящик кілька функцій. Кожна функція – це окремий інструмент, що виконує свою власну роботу. У вас може бути одна функція для реєстрації користувачів, інша – для обробки завантажених зображень і третя – для надсилання нічних звітів. Усі вони знаходяться в одному ящику, але працюють незалежно. Ще дещо про функції «Вони за своєю природою не мають стану» – стейтлас. Це означає, що вони нічого не пам'ятають між запусками. Якщо ваша функція обробила файл і завершила роботу – на цьому все. Наступного разу вона запускається з чистого аркуша без жодних спогадів про попередній запуск. Це звучить як обмеження, але насправді саме ця особливість робить їх такими потужними. Оскільки функції не зберігають пам'ять чи стан, Azure може миттєво запустити 100 копій вашої функції під час стрибків трафіку і так само швидко вимкнути їх, коли трафік падає. Ось як ви отримуєте масштабованість, не сплачуючи за простоюючі сервери. Виникає питання, якщо функція просто стоїть і нічого не робить, поки щось її не розбудить, то що саме її будить? Саме тут на допомогу приходять тригери. Тригери – це коли? Кожна функція повинна мати рівно один тригер, і це обов'язково. Тригер – це подія, яка змушує вашу функцію прокинутися. Без нього ваш код просто стоятиме і не робитиме абсолютно нічого. Уявіть тригери як дверний дзвінок. Ваша функція знаходиться всередині будинку і чекає. Вона може чекати нескінченно довго. Нічого не станеться, доки хтось не подзвонить у двері. Тоді функція миттєво активується, відчиняє двері, виконує свою роботу і повертається в режим очікування. Існує чотири типи тригерів, з якими новачки стикаються найчастіше. HTTP-тригер – це найпоширеніша точка відліку. Хтось відвідує URL або робить ARRI запит, і ваша функція спрацьовує. Саме так ви створюєте легковагові ARRI без налаштування повноцінного веб-сервера. Також існує таймерний тригер, який запускається за розкладом. Ви задаєте крон-вираз, наприклад, виконання щогодини або о півночі щоночі, і ваша функція запускається саме в цей час. Це ідеально підходить для завдань з обслуговування, очищення або створення нічних звітів. Тригер-блоб об'єкта спрацьовує, коли файл завантажується в Azure Storage. Скажімо, хтось завантажує PDF-файл у певну папку. Тригер-блоб об'єкта виявляє це завантаження і автоматично запускає вашу функцію. Це дуже корисно для обробки зображень, конвертації документів та перевірки файлів. А тригер-черги спрацьовує, коли в черзі з'являється повідомлення. Черги – це спосіб роз'єднати різні частини вашої системи. Один сервіс додає повідомлення в чергу, а ваша функція підхоплює його і обробляє, коли буде готова. Це запобігає ситуації, коли один повільний сервіс блокує роботу всього іншого. Ось головний момент. Коли тригер спрацьовує, він автоматично передає дані у вашу функцію. Вам не потрібно опитувати систему або перевіряти, чи щось сталося. Тригер надає вам усе необхідне, а ваша функція просто це обробляє. Функція без тригера – це просто код, який нічого не робить. Тригер – це те, що дає їй призначення. Отже, тригер підказує вашій функції, коли працювати. Але звідки беруться дані і куди вони йдуть? Ось тут на допомогу приходять прив'язки bindings. Прив'язки – дані на вхід, дані на вихід. Прив'язки – це спосіб вказати функції, які дані читати і куди надсилати результати, не пишучи зайвий код. Це звучить складно, тож дозвольте спростити. Існує два типи. Вхідні прив'язки передають дані у вашу функцію. Вихідні прив'язки відправляють дані назовні. Без прив'язок вам довелося б щоразу писати коди SDK для взаємодії зі сховищем, базою даних чи чергою. Вам довелося б керувати рядками підключення, повторними спробами, серіалізацією та десеріалізацією даних. Це занадто багато шабленого коду лише для того, щоб прочитати файл. З прив'язками ви просто оголошуєте те, що вам потрібно. Ви кажете «Я хочу читати з цього контейнера блоб» або «Я хочу писати в цю чергу». Виконувальне середовище бере на себе все інше. Воно відкриває з'єднання, считує дані і передає їх у вашу функцію як параметр. Коли функція завершує роботу, вона бере результат і записує його туди, куди ви вказали. Уявіть прив'язки як труби. Ви з'єднуєте свою функцію зі сховищем, базою даних або чергою. Дані протікають через ці труби автоматично. Вашій функції не потрібно знати, як працюють ці труби. Вона просто отримує те, що надходить, і відправляє те, що має вийти. Ось конкретний приклад. Скажімо, у вас є вхідна прив'язка до блоб-об'єкта. Коли ваша функція запускається, вона автоматично считує файл із блоб-сховища та передає його вам як параметр. Вам не потрібно писати жодного коду SDK для сховища. Ви просто отримуєте дані та обробляєте їх. Інший приклад – прив'язка виводу до черги. Ваша функція щось опрацьовує і наприкінці повертає значення. Середовище виконання бере це значення, все реалізує його та додає до черги. Ви не пишете ніякого коду для черги. Ви просто повертаєте значення. Прив'язки є необов'язковими. Їх може бути нуль, одна або багато. Деяким функціям потрібен лише тригер без жодних прив'язок. Інші можуть мати три або чотири прив'язки до різних службових. Поєднання тригерів і прив'язок робить Azure Function з такими потужними. Ви пишете бізнес-логіку, сам код для прийняття рішень. Платформа бере на себе всю інтеграцію. Ваша функція залишається невеликою, цілеспрямованою та зрозумілою. Питання ціноутворення Ціноутворення – це те, що дивує більшість початківців. Для більшості людей план споживання «Консампшенплен» є типовим вибором і в 90% випадків варто починати саме з нього. Ось як це працює. Ви платите лише тоді, коли ваша функція реально виконується. Коли вона неактивна, ви нічого не платите. Нуль, жодної копійки. Рахунок складається з двох компонентів. По-перше, кількість виконань, скільки разів спрацювала ваша функція. По-друге, час виконання, що вимірюється в так званих «ГБ-секундах». Це, по суті, тривалість роботи вашої функції, помножена на використаний обсяг пам'яті. Безкоштовна квота є щедрою. Ви отримуєте 1 мільйон виконань на місяць і 400 тисяч гігабайтів секунд абсолютно безкоштовно. Для більшості малих проєктів, хобі-додатків та прототипів ви ніколи не заплатите ні цента. Ніколи. Якщо ви перевищите безкоштовну квоту, тарифи все одно залишаються дуже низькими. 20 центів за мільйон виконань. Це не помилка. 20 центів за мільйон запусків. Уявіться, як оплату за електрику лише тоді, коли ви клацаєте вимикач. Немає щомісячної базової плати за наявність проводки у стінах. Ви платите лише за енергію, яку фактично використовуєте. Звісно, існують і інші плани. Flex Consumption новіший і надає підтримку віртуальних мереж. Premium підтримує ваші функції завжди гарячими, тому затримок при холодному старті немає. Dedicated надає вам фіксовані потужності на традиційному плані App Service. Але для початку роботи Consumption це майже завжди правильний вибір. Однак є одне застереження. Безкоштовна квота розподіляється між усіма вашими функціональними додатками в межах однієї підписки. Якщо у вас 10 додатків, вони всі використовують той самий мільйон безкоштовних виконань. Тож слідкуйте за цим, якщо почнете створювати більше кількох додатків. Ціноутворення чудове. Але давайте перейдемо до реального прикладу. Сценарій із реального життя. Уявіть, що ви керуєте веб-сайтом, куди користувачі завантажують фотопрофілю. Ці зображення величезні, наприклад, по 10 МБ кожне. І це спричиняє кілька реальних проблем. Великі файли дорожче зберігати, вони сповільнюють сайт при завантаженні сторінок і дратують користувачів, які змушені чекати на фото. Отже, вам потрібен спосіб автоматичного стиснення цих зображень. Без Azure Functions вам довелося б створювати фоновий робочий процес з нуля. Це означає пошук окремого сервера, налаштування черги для керування навантаженням та написання коду для всіх цих компонентів. Це купа зайвої складності для такої простої справи, як стиснення зображення. З Azure Functions вам потрібен лише один тригер-блоб-сховища та одна функція. Жодних турбот про сервери. Дозвольте пояснити, як це працює. Користувач завантажує фото на ваш сайт і файл потрапляє в Azure Blob Storage. Щойно він з'являється там, автоматично спрацьовує тригер-блоб-сховища. Ваша функція прокидається, запускає код стиснення і зберігає зменшену версію назаду у сховище. Все це відбувається за лічені секунди. Користувач не чекає, бо весь процес відбувається у фоновому режимі абсолютно непомітно. Ось ще один повсякденний приклад – надсилання вітального листа, коли хтось реєструється у вашому сервісі. HTTP-тригер перехоплює запит на реєстрацію з вашого сайту. Ваша функція активується, бере адресу електронної пошти користувача, надсилає вітальне повідомлення через SendGrid і все готово. Користувач отримує лист майже миттєво. Не потрібно налаштовувати поштовий сервер чи чергу відправлення. Лише одна функція, одна робота і готово. Саме для таких завдань і були створені Azure Functions. Невеликі, цілеспрямовані, подієві завдання. Немасивні додатки, нескладні робочі процеси, а одна добре виконана справа ініційована подією десь в іншому місці. Коли використовувати Azure Functions? Тож коли варто братися за функцію, а коли краще використати щось інше? Ось швидкий спосіб прийняти рішення. Запитайте себе, чи є завдання коротким, чи воно подієве і чи є воно безстатусним. Якщо ви відповіли так на всі три питання, Azure Functions – ймовірно правильний інструмент. Почнемо з вдалих варіантів використання. ARRI та WEBHOOK ідеально для цього підходять. Вам потрібна легка кінцева точка, яка відповідає на HTTP-запит, виконує одну дію і повертає результат саме для цього створені HTTP-тригери. Обробка файлів та зображень – ще один важливий випадок. Файл потрапляє у сховище, функція запускається, обробляє його і зберігає результат, і все це без сервера. Заплановані завдання, як отнічне очищення або створення звітів, чудово працюють із таймерами. Перетворення даних для ETL-конвейерів також є поширеним явищем. Функції ідеально підходять для інтеграції, поєднуючи сервіси, які не взаємодіють самі по собі. Тепер поговоримо про те, коли функції не є найкращим рішенням. Довготривалі процеси – це проблема, оскільки в плані споживання функції мають ліміт часу 5 хвилин за замовчуванням або до 10 хвилин, якщо налаштувати. Якщо ваше завдання триває довше, вам потрібне інше рішення. Станові додатки – ще одна невідповідність. Функції нічого не запам'ятовують між запусками. Якщо вам потрібно підтримувати стан сеансу або відстежувати прогрес між кроками, це суперечить їхній архітектурі. Важкі обчислювальні навантаження також не підходять. Якщо вам потрібен тривалий час роботи процесора, краще обрати віртуальну машину або контейнер. Складні робочі процеси, де одне завдання залежить від іншого, краще обробляти через Jura Ball Functions або Logic Apps. Ось короткий огляд альтернатив. Azure Logic Apps – це варіант без написання коду для підключення сервісів. Якщо вам не потрібно писати власний код, Logic Apps впораються із завданням через візуальний редактор. Azure App Service призначений для повноцінних веб-додатків, що працюють 24 сьомих. Якщо вам потрібен повноцінний сайт або ARRI, що працює постійно, це ваш інструмент. Azure Container Apps надає контейнеризовані мікросервіси з більшим контролем над середовищем виконання. А Azure Virtual Machines дає повний контроль над операційною системою, якщо це потрібно. Ось просте правило. Якщо ви можете описати завдання одним реченням, це, імовірно, чудовий кандидат для функції. Стиснути зображення після завантаження. Надіслати привітальний лист після реєстрації користувача. Виконувати очищення щоночі о півночі. Одне речення, одне завдання, одна функція. Поширені помилки новачків, яких варто уникати. Тепер поговоримо про кілька моментів, на які варто звернути увагу. Це помилки, на яких майже всі спідкуються на початку. Типова помилка новачків – думати, що функції завжди безкоштовні. Безкоштовний ліміт щедрий, мільйон виконань звучить вагомо, але якщо ваша функція стане популярною або зазнає атаки ботів, ліміт швидко вичерпається. Тож стежте за використанням, налаштуйте бюджетні сповіщення Azure і не отримуйте несподіваних рахунків наприкінці місяця. Ще одна помилка – ігнорування холодних стартів. Коли функція запускається після періоду бездіяльності, це займає більше часу. У плані споживання це може тривати кілька секунд. Для більшості випадків це прийнятно. Але якщо ви створюєте арі, чутливий до затримок, де важлива кожна мілісекунда, розгляньте преміум-план або увімкніть постійно готові екземпляри. І ще одна помилка – написання функцій, які працюють надто довго. План споживання має тайм-аут – 5 хвилин за замовчуванням, максимум 10 хвилин. Якщо ваша функція обробляє файл 15 хвилин, її буде примусово зупинено на півдорозі. Розбийте це завдання на менші частини або оберіть інший план розміщення. Ще одна часта помилка – не використовувати розгортання, запуск із пакета. Це проста зміна конфігурації, що покращує холодний старт і робить розгортання надійнішим. Замість копіювання окремих файлів ви розгортаєте zip-пакет. Це одна позначка на порталі – просто зробіть це. Відкриття HTTP endpoint-пинтів без автентифікації – ще одна пастка. Легко залишити функцію анонімною під час тестування, а потім забути обмежити доступ. Встановлюйте рівень авторизації правильно з самого початку. Використовуйте ключі функції або адміністратора. Не залишайте двері відчиненими. Використання одного облікового запису зберігання для кількох функціональних застосунків – теж проблема. Під час розробки спільно використовувати їх можна. У робочому середовищі кожен застосунок повинен мати власний обліковий запис зберігання. Інакше виникне проблема галасливого сусіда, коли трафік однієї функції сповільнює іншу. І нарешті – відмова від увімкнення Application Insights. Без нього ви працюєте на осліп. Ви не бачите мете збоїв, помилок чи проблем із продуктивністю. Ви не знатімєте, чи працює функція занадто довго, чи завершується з помилкою тихо. Увімкніть це з першого дня. Це займає 30 секунд і рятує від годин налагодження. Головне правило всього цього – функції мають бути малими, цілеспрямованими та безстановою. Одне завдання на одну функцію – нічого більше. Отже, це вся система. Azure Functions – це безсерверні обчислення, що запускають фрагменти коду у відповідь на події. Ви платите лише тоді, коли ваш код виконується. Тригери вказують функції, коли прокидатися, прив'язки підключають її до потрібних даних, а план споживання робить її майже безкоштовною для малих проєктів. Ваш найкращий крок зараз – створити просту функцію з HTTP тригером на порталі Azure. Це займає 5 хвилин і нічого не коштує. Підпишіться на Microsoft Knowledge Nuggets для простих пояснень і поділіться цим із тим, хто постійно запитує, що таке серверлес. Фрав.