Ось твій урок у стилі CS50, адаптований під тему Upstreams та Health Checks.
🎓 CS50: Архітектура високих навантажень
Тема: Upstreams та Health Checks (Групи серверів та перевірка їх здоров'я)
1. 🔥 Вступ: Чому один сервер — це шлях в нікуди?
Уявіть, що ви прийшли до супермаркету. Величезний гіпермаркет перед святами. І там працює лише одна каса.
Що станеться? Черга розтягнеться на кілометри. Касир втомиться, почне помилятися, а потім, можливо, просто втратить свідомості від перенавантаження. Робота магазину зупиниться. Гнів покупців досягне критичної маси.
А тепер уявіть, що ви — головний менеджер. Що ви зробите? Правильно, ви відкриєте ще 5 кас.
Але є нюанс! Покупці (клієнти) не знають, яка каса вільна, а яка закрита на перерву. Їм потрібен хтось на вході, хто скаже: "Ти йди на касу 1, ти — на касу 2, а на касу 3 не йди — там стрічка зламалася".
У світі веб-розробки: * Ви (менеджер/регулювальник) — це Load Balancer (наприклад, Nginx). * Група кас — це Upstream (набір серверів). * Перевірка, чи не зламалася каса — це Health Check.
Питання до тебе: Якби ти писав Instagram, ти б довірив усі фотографії світу одному комп'ютеру? Звісно, ні. Тобі потрібна армія серверів. Сьогодні ми навчимося керувати цією армією.
2. 🧠 Теоретична база: Що там "під капотом"?
Давайте розберемо це без складних академічних термінів.
Що таке Upstream?
У конфігурації (наприклад, Nginx) це просто список адрес. Ти кажеш: "Дивись, у мене є не один бекенд, а ціла пачка".
Замість того, щоб слати запит на конкретний localhost:3000, ми шлемо його на віртуальне ім'я групи, наприклад my_app. А вже всередині цієї групи Nginx сам вирішує, кому саме передати "естафету".
Що таке Health Check?
Це механізм, який дозволяє не відправляти користувачів на "мертвий" сервер.
Є два типи перевірок (запам'ятай цю різницю!):
-
Passive Health Checks (Пасивні): Це як у футболі. Тренер (Nginx) не знає, що гравець травмований, поки не дасть йому пас.
- Логіка: Nginx пробує відправити запит на сервер А. Сервер А видає помилку або мовчить. Nginx каже: "Окей, ти слабка ланка, я тебе тимчасово викреслюю і спробую сервер Б".
- Де працює: У безкоштовній версії Nginx (Open Source).
-
Active Health Checks (Активні): Це як лікарський огляд. Тренер періодично питає гравця: "Ти як? Живий? Дихаєш?".
- Логіка: Балансувальник сам, фоново, шле спеціальні запити (наприклад, на
/health) кожні 5 секунд. Якщо сервер відповів "200 OK" — він у грі. Якщо ні — на нього не йде трафік взагалі. - Де працює: Nginx Plus (платно), AWS ALB, HAProxy.
- Логіка: Балансувальник сам, фоново, шле спеціальні запити (наприклад, на
Інтуїтивно: Upstream — це команда. Health Check — це спосіб зрозуміти, хто з команди сьогодні вийшов на роботу, а хто захворів.
3. 🧪 Приклади: Від простого до реального
Приклад 1: "Наївний" Upstream
Ти очікуєш, що ми просто перелічимо сервери, так?
http {
# Визначаємо групу серверів з назвою 'backend_servers'
upstream backend_servers {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}
server {
listen 80;
location / {
# Передаємо запит не на IP, а на ГРУПУ
proxy_pass http://backend_servers;
}
}
}
Що тут відбувається: Nginx за замовчуванням буде кидати запити по колу (Round Robin). Перший запит — на 3001, другий — на 3002, третій — на 3003, четвертий — знову на 3001.
Приклад 2: Додаємо виживання (Passive Health Checks)
А що, якщо сервер на порту 3002 "впав"? У прикладі вище Nginx спробує туди стукатись і користувач отримає помилку або затримку.
Давайте це виправимо. Що ти очікуєш побачити? Налаштування, які кажуть: "Якщо сервер помилився X разів, не чіпай його Y секунд".
upstream backend_servers {
# max_fails=3 -> Якщо 3 рази підряд помилка...
# fail_timeout=30s -> ...то вважаємо сервер мертвим на 30 секунд.
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3002 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3003 max_fails=3 fail_timeout=30s;
}
Чому це круто: Якщо 3002 "помер", Nginx після трьох невдач перестане слати туди людей. Клієнти навіть не помітять проблеми, бо їх автоматично перекине на 3001 або 3003! Це і є High Availability (Висока Доступність).
4. 🛠 Практична частина
Час "забруднити руки" кодом. Уяви, що ти DevOps інженер.
Завдання 1: Створення кластера
Напиши блок upstream, який називається my_api і містить два сервери: 10.0.0.5 та 10.0.0.6. Налаштуй proxy_pass на цей апстрім.
Завдання 2: "Правило трьох ударів"
Модифікуй попередній блок. Зроби так, щоб сервер 10.0.0.5 вважався "мертвим" на 10 секунд, якщо він провалив лише 1 запит. (Це жорстко, але спробуй).
Завдання 3: Нерівність (Ваги)
Уяви, що 10.0.0.5 — це потужний сервер за $1000, а 10.0.0.6 — старий ноутбук.
Дослідницьке завдання: Знайди параметр weight у документації Nginx. Зроби так, щоб на потужний сервер йшло в 3 рази більше запитів, ніж на слабкий.
Завдання 4: Питання "А що, якщо..." У тебе в апстрімі 2 сервери. Обидва впали (повернули 500 помилку або не відповідають). Що побачить користувач? (Варіанти: 404, 502 Bad Gateway, вічне завантаження). Правильна відповідь — 502, але чому?
5. 💡 Мислення як у розробника
Як відрізнити новачка від профі в цій темі?
-
Новачок думає: "Сервери працюють вічно". Профі знає: "Усе, що може зламатися, зламається". Профі завжди налаштовує
fail_timeout, бо мережа ненадійна. -
Помилка новачка: Не налаштовувати тайм-аути з'єднання (
proxy_connect_timeout). Ситуація: Сервер завис і не відкидає з'єднання, а просто "висить". Без тайм-ауту Nginx (і клієнт) чекатиме 60 секунд. Це вічність! Профі ставить короткі тайм-аути (наприклад, 2-5 секунд), щоб швидко зрозуміти, що сервер мертвий, і спробувати інший. Fail Fast! (Падай швидко). -
Порада з практики: Завжди роби в своєму додатку спеціальний роут
GET /health. Нехай він просто повертає JSON{"status": "ok"}. Це дозволить налаштувати просунуті перевірки (через AWS або Consul), які не просто пінгують порт, а перевіряють, чи жива база даних і чи працює додаток логічно.
6. 🧩 Підсумок
Отже, що ми сьогодні розібрали?
- Upstream — це не один воїн у полі, а цілий загін серверів, об'єднаних під одним ім'ям.
- Passive Health Checks — це коли ми банимо сервер, якщо він "накосячив" на реальних запитах.
- Ви тепер вмієте масштабувати (додавати сервери в список) і забезпечувати надійність (ізолювати зламані сервери).
Тепер ви не просто "кодери", ви — архітектори, які будують системи, стійкі до катастроф.
🔜 У наступній серії: Ми навчилися розподіляти запити. Але як саме? По черзі? Чи тому, хто менш завантажений? Ми поговоримо про алгоритми балансування навантаження (Load Balancing Algorithms). Least Connections, IP Hash та магія Sticky Sessions.
Не перемикайтесь! Це був CS50. 👋