
Повноцінний вебсервіс не обов’язково повинен працювати на орендованому сервері, за який доводиться платити щомісяця незалежно від кількості користувачів.
Для невеликого SaaS можна використати серверну архітектуру AWS: код запускається лише під час запиту, база даних оплачується за виконані операції, а файли зберігаються в дешевому об’єктному сховищі.
Розглянемо таку модель на прикладі сервісу скорочення посилань. Користувач реєструється, додає довгу адресу, отримує коротке посилання, переглядає статистику та за потреби переходить на платний тариф.
За правильної конфігурації близько одного мільйона переходів на місяць можуть коштувати приблизно $1,50–1,60. Проте ця сума стосується лише базової інфраструктури та певного рівня навантаження. Вона не включає реєстрацію домену, податки, комісії платіжної системи й додаткові платні функції.
Перш ніж ми продовжимо, переконайтеся, що ви підписані на мій телеграм канал — у мене є преміум-контент (безкоштовно для підписників), а також залишайтеся на зв’язку зі мною!
Чому звичайний сервер може бути невигідним
Найпростіший спосіб запустити вебзастосунок — орендувати віртуальний сервер, встановити базу даних і розмістити на ньому код.
Але платити доведеться навіть тоді, коли сервісом ніхто не користується. Крім цього, власник повинен:
налаштовувати операційну систему;
встановлювати оновлення безпеки;
контролювати доступне місце;
стежити за навантаженням;
налаштовувати резервні копії;
масштабувати базу даних;
відновлювати систему після збоїв.
Для сервісу з нерівномірним трафіком це часто означає оплату ресурсів, які більшу частину часу простоюють.
Serverless-архітектура працює інакше. Окремого постійно запущеного сервера немає. AWS автоматично запускає необхідний код у відповідь на запит і зупиняє його після завершення операції.
Це не робить інфраструктуру безкоштовною, але дозволяє прив’язати основну частину витрат до реального використання.
Що входить до сервісу
Щоб скорочувач посилань можна було вважати SaaS, одного перенаправлення недостатньо. Потрібні щонайменше:
реєстрація та вхід;
особистий кабінет;
створення коротких посилань;
редагування і видалення посилань;
обмеження відповідно до тарифу;
статистика переходів;
приймання оплати;
розподіл даних між користувачами;
захищений API;
власний домен і HTTPS;
журналювання помилок;
контроль витрат.
Для цього можна зібрати систему з декількох керованих сервісів AWS.
Основні компоненти архітектури
Компонент | Завдання |
|---|---|
Amazon S3 | Зберігає файли особистого кабінету |
Amazon CloudFront | Доставляє сторінки користувачам і кешує статичні файли |
Amazon Cognito | Реєструє користувачів і перевіряє їхню особу |
Amazon API Gateway | Приймає запити від сайту й коротких посилань |
AWS Lambda | Створює посилання, перевіряє тарифи та виконує перенаправлення |
Amazon DynamoDB | Зберігає посилання, власників і налаштування |
Amazon Route 53 | Підключає домен до інфраструктури |
AWS Certificate Manager | Видає сертифікат HTTPS |
Amazon CloudWatch | Збирає помилки, показники та журнали |
Amazon SQS | За потреби передає події для асинхронного підрахунку статистики |
У базовій конфігурації достатньо двох основних Lambda-функцій:
Management Function — створення, перегляд, редагування та видалення посилань.
Redirect Function — пошук короткого коду та перенаправлення відвідувача.
Окрему функцію для статистики можна додати пізніше, коли кількість переходів зросте.
Як працює особистий кабінет
Інтерфейс можна створити на React, Vue або іншому клієнтському фреймворку. Після складання він перетворюється на набір статичних файлів: HTML, JavaScript, CSS, шрифти й зображення.
Ці файли розміщуються в Amazon S3, а CloudFront доставляє їх відвідувачам через найближчі доступні вузли.
Під час першого відкриття CloudFront отримує файл зі сховища. Наступні запити можуть обслуговуватися з кешу, тому S3 не потрібно щоразу передавати ті самі дані.
У результаті особистий кабінет:
не потребує окремого вебсервера;
швидко відкривається в різних регіонах;
автоматично витримує нерівномірний трафік;
майже нічого не коштує за невеликого обсягу файлів.
Прямий публічний доступ до S3 краще закрити. CloudFront повинен отримувати файли через спеціально налаштований захищений доступ.
Реєстрація користувачів через Amazon Cognito
Самостійна реалізація авторизації створює багато ризиків. Потрібно безпечно зберігати паролі, відновлювати доступ, підтверджувати електронну адресу та захищати облікові записи.
Amazon Cognito бере цю частину на себе. Після входу користувач отримує спеціальний токен, який додається до запитів особистого кабінету.
API Gateway перевіряє токен і лише після цього передає запит у Lambda. Таким чином функція отримує підтверджений ідентифікатор користувача.
Для прямої авторизації без корпоративних систем Cognito має постійний безкоштовний рівень до 10 000 активних користувачів на місяць у тарифах Lite та Essentials. Окремо можуть оплачуватися листи для підтвердження адреси й відновлення пароля.
Як створюється коротке посилання
Процес можна розділити на декілька операцій:
Користувач входить до особистого кабінету.
Вставляє довгу адресу.
Кабінет надсилає запит до API Gateway.
API Gateway перевіряє токен Cognito.
Lambda перевіряє адресу, тариф і доступний ліміт.
Функція генерує випадковий короткий код.
DynamoDB перевіряє, чи не зайнятий цей код.
Запис зберігається в таблиці.
Користувач отримує готове коротке посилання.
Наприклад:
https://short.example/a7Kp2QКод краще генерувати випадково, а не створювати зі звичайного порядкового номера. Послідовні значення легко перебирати, через що стороння людина може знаходити чужі посилання.
Для запису варто використовувати умовну операцію: новий елемент додається лише тоді, коли такого коду ще немає. Якщо відбулося рідкісне зіткнення, функція створює іншу комбінацію.
Що зберігати в DynamoDB
Для першої версії достатньо однієї таблиці.
Основний запис може містити:
короткий код;
початкову адресу;
ідентифікатор власника;
дату створення;
статус посилання;
тип перенаправлення;
термін дії;
назву кампанії;
тариф користувача;
загальну кількість переходів.
Короткий код використовується як основний ключ. Завдяки цьому функція перенаправлення отримує потрібний запис однією операцією читання.
Щоб показати всі посилання конкретного користувача, можна додати індекс за ідентифікатором власника та датою створення.
Поле завершення терміну дії дозволяє налаштувати автоматичне видалення прострочених записів через DynamoDB TTL. Це допомагає не накопичувати непотрібні дані.
Як відбувається перенаправлення
Коли відвідувач відкриває коротку адресу, запит надходить до API Gateway, а потім — до Redirect Function.
Функція:
отримує короткий код з адреси;
шукає запис у DynamoDB;
перевіряє статус і термін дії;
повертає відповідь із кодом перенаправлення;
браузер відкриває початкову сторінку.
Для звичайного короткого посилання можна використовувати тимчасове перенаправлення 302. Воно підходить, якщо користувач може пізніше змінити цільову адресу.
Постійне перенаправлення 301 слід використовувати обережно. Браузери та пошукові системи можуть його кешувати, тому зміна початкової адреси не завжди відразу вплине на попередніх відвідувачів.
Чому статистику краще рахувати окремо
Найпростіше рішення — після кожного переходу одразу збільшувати лічильник у DynamoDB.
Для невеликого проєкту це працює. Але популярне посилання створюватиме багато записів в одному й тому самому елементі таблиці. Це збільшує витрати та може створити точку високого навантаження.
Практичніший варіант:
Redirect Function виконує перенаправлення без очікування статистики.
Подія про перехід надсилається в чергу.
Окрема Lambda отримує події пакетами.
Дані групуються за короткими кодами.
Лічильники оновлюються одним набором операцій.
Відвідувач отримує перенаправлення швидше, а коротка затримка статистики на декілька секунд не впливає на роботу сервісу.
Проте черга, додаткова функція, детальна географічна аналітика та тривале зберігання подій можуть збільшити рахунок. Для першої версії достатньо загальної кількості переходів і статистики за днями.
Як підключити платні тарифи
Платіжна система не повинна передавати секретні ключі до браузера або покладатися лише на відповідь сторінки після оплати.
Безпечніша схема виглядає так:
Користувач вибирає тариф.
Management Function створює платіжну сесію.
Платіжна система приймає оплату.
Після завершення вона надсилає захищене службове повідомлення.
Lambda перевіряє підпис повідомлення.
У профілі користувача змінюється тариф і дата наступної оплати.
Тариф можна зберігати в окремому записі DynamoDB. Перед створенням нового посилання функція перевіряє встановлені обмеження.
Наприклад:
Тариф | Посилання | Базова статистика | Власний код |
|---|---|---|---|
Безкоштовний | 25 | Так | Ні |
Стартовий | 500 | Так | Так |
Професійний | 10 000 | Розширена | Так |
Комісія платіжної системи не входить у вартість AWS. Також потрібно передбачити скасування підписки, невдале списання, повернення коштів і повторне надходження одного повідомлення.
Розрахунок витрат
Візьмемо такий сценарій:
регіон AWS — US East;
1 000 000 переходів на місяць;
10 000 запитів з особистого кабінету;
10 000 нових або змінених посилань;
записи DynamoDB менші за 1 КБ;
відповіді DynamoDB менші за 4 КБ;
Lambda має 128 МБ пам’яті;
середня тривалість виконання — до 50 мс;
у Cognito менше 10 000 активних користувачів;
статичні файли кешуються через CloudFront;
журнали не містять повних тіл кожного запиту.
Орієнтовна калькуляція:
Сервіс | Розрахунок | Приблизна сума |
|---|---|---|
API Gateway HTTP API | 1,01 млн запитів | $1,01 |
AWS Lambda | Основна частина в постійному безкоштовному ліміті | до $0,01 |
DynamoDB — читання | Близько 1 млн невеликих читань | $0,06 |
DynamoDB — запис | Близько 10 000 операцій | $0,01 |
Route 53 | Одна публічна DNS-зона | $0,50 |
S3 і CloudFront | Невеликий сайт із кешуванням | $0–0,01 |
Cognito | До 10 000 активних користувачів | $0 |
CloudWatch | За мінімального обсягу журналів | $0 |
Разом | близько $1,58–1,60 |
Це розрахунок порядку витрат, а не гарантований рахунок. Ціни відрізняються між регіонами, а AWS може змінювати тарифи.
Нові акаунти також можуть отримувати кредити та тимчасові безкоштовні ліміти. У наведеній сумі вони не враховані, щоб калькуляція не залежала від стартової акції.
Деякі витрати можна додатково знизити за допомогою безкоштовного плану CloudFront, до якого входять певні ліміти CDN, DNS, захисту та журналювання. Перед запуском потрібно перевірити доступні умови для конкретної конфігурації.
Що не входить у $1,50
Базова калькуляція не враховує:
щорічну реєстрацію домену;
податки та конвертацію валюти;
комісію платіжної системи;
масове надсилання електронних листів;
SMS-підтвердження;
детальну аналітику кожного переходу;
тривале зберігання журналів;
автоматичні резервні копії з відновленням до будь-якої миті;
роботу в декількох регіонах;
виділену пропускну здатність;
платні засоби захисту;
перевірку адрес на фішинг і шкідливі сайти;
підтримку власних доменів клієнтів.
Якщо кожен перехід зберігає IP-адресу, країну, пристрій, браузер і джерело, кількість операцій запису швидко зростає. Тоді вартість аналітики може перевищити вартість самих перенаправлень.
Чому витрати можуть раптово зрости
Serverless не означає автоматично дешево. Якщо програма виконає мільярд невдалих запитів, AWS виставить рахунок за мільярд операцій.
Найчастіші причини несподіваних витрат:
відкритий API без обмеження частоти запитів;
бот, який безперервно перебирає короткі коди;
помилка з нескінченним повторенням операції;
надто детальні журнали;
великі відповіді API;
Lambda з надлишковою пам’яттю та довгим виконанням;
увімкнена Provisioned Concurrency;
платний кеш API Gateway;
підключення функцій до VPC через NAT Gateway;
резервні копії й реплікація, увімкнені без розрахунку;
зберігання секретів у платному сервісі;
запис аналітики після кожного переходу.
Особливо небезпечним для дешевого проєкту є NAT Gateway. Його погодинна оплата та вартість переданих даних можуть в багато разів перевищити весь початковий бюджет.
Як захистити сервіс і бюджет
Ще до відкриття реєстрації потрібно:
Налаштувати сповіщення про витрати.
Встановити декілька бюджетних порогів, наприклад $1, $5 і $20.
Обмежити кількість створених посилань для кожного тарифу.
Установити ліміти запитів до API.
Задати максимальну тривалість виконання Lambda.
Обмежити зарезервовану конкурентність функцій.
Встановити короткий термін зберігання журналів.
Не записувати паролі, токени й повні платіжні дані.
Перевіряти формат і довжину кожної адреси.
Заборонити небезпечні протоколи й внутрішні службові адреси.
Додати можливість поскаржитися на шкідливе посилання.
Передбачити блокування користувача та всіх його адрес.
Публічний скорочувач посилань швидко привертає увагу спамерів і шахраїв. Тому захист від зловживань є не додатковою функцією, а частиною основного продукту.
Чи витримає архітектура тисячі запитів
Lambda, API Gateway та DynamoDB можуть автоматично масштабуватися, але це не означає необмежену пропускну здатність.
AWS застосовує регіональні квоти на кількість одночасних запусків Lambda та запитів до API. DynamoDB також має правила масштабування й захисту окремих розділів таблиці.
Перед запуском рекламної кампанії потрібно провести навантажувальне тестування та перевірити:
кількість запитів за секунду;
затримку перенаправлення;
частоту помилок;
кількість одночасних Lambda-функцій;
тривалість холодного запуску;
навантаження на ключі DynamoDB;
обсяг журналів;
прогнозований рахунок.
Мільйон переходів на місяць — це в середньому менше одного запиту за секунду. Сервіс може переживати короткі сплески в сотні або тисячі запитів, але постійне навантаження в тисячу запитів за секунду матиме зовсім іншу вартість.
Покроковий план запуску
Крок 1. Описати мінімальну версію
Для першого запуску достатньо:
реєстрації;
створення посилання;
перенаправлення;
списку посилань;
видалення;
загального лічильника переходів;
одного платного тарифу.
Власні домени, QR-коди, командний доступ і складну аналітику можна додавати після перевірки попиту.
Крок 2. Створити DynamoDB-таблицю
Потрібно визначити ключі, індекс користувача та поле автоматичного видалення. Для нерівномірного нового навантаження зручно почати з режиму оплати за запити.
Крок 3. Реалізувати дві Lambda-функції
Management Function працює лише з авторизованими запитами. Redirect Function залишається публічною, але має суворо перевіряти короткий код і повертати лише необхідну відповідь.
Крок 4. Налаштувати HTTP API
HTTP API зазвичай дешевший і простіший за REST API Gateway. Для базового SaaS його можливостей достатньо.
Маршрути можуть виглядати так:
POST /links
GET /links
PATCH /links/{code}
DELETE /links/{code}
GET /{code}
POST /billing/webhookКрок 5. Додати авторизацію
Закриті маршрути підключаються до Cognito. Публічним залишається лише перенаправлення та службова адреса платіжної системи з обов’язковою перевіркою підпису.
Крок 6. Розмістити інтерфейс
Готові файли завантажуються в S3. CloudFront підключає кешування, HTTPS і домен особистого кабінету.
Крок 7. Описати інфраструктуру кодом
Ресурси краще створювати через AWS SAM, CDK або Terraform. Це дозволяє відтворити середовище, бачити зміни та не налаштовувати кожну функцію вручну.
Крок 8. Підключити моніторинг
Потрібні сповіщення про:
помилки Lambda;
збільшення тривалості виконання;
обмеження кількості запусків;
відповіді API з помилками;
перевищення бюджету.
Крок 9. Провести тестування
Окремо перевіряються авторизація, зіткнення коротких кодів, прострочені посилання, скасовані тарифи, повторні повідомлення платіжної системи та спроби відкрити чужі дані.
Чи можна назвати такий сервіс готовим до роботи
Serverless-компоненти дають міцну основу: автоматичне масштабування, керовану базу даних, захищену авторизацію та мінімальні витрати під час простою.
Однак сама назва AWS не робить застосунок готовим до реальних користувачів. Потрібні:
перевірка вхідних даних;
ізоляція облікових записів;
контроль тарифів;
обробка помилок;
захист від ботів;
політика конфіденційності;
резервне копіювання;
навантажувальне тестування;
процедура видалення даних;
сповіщення про витрати.
Приблизно $1,50 на місяць — реалістична стартова вартість базової інфраструктури за визначеного навантаження. У цьому й полягає перевага serverless: можна запустити продукт із невеликими витратами, перевірити попит, знайти перших платних користувачів і лише після цього ускладнювати систему.
Головне — не плутати автоматичне масштабування з необмеженими ресурсами, а низьку початкову ціну — з постійною вартістю незалежно від трафіку.