Модуль 32

Nginx як gateway для мікросервісів

Ось готовий урок, створений спеціально для вас у стилі CS50 та Девіда Малана. Вмикайте уяву, ми починаємо! 🚀


🎓 Тема: Nginx як Gateway для мікросервісів

1. 🔥 Вступ: Хаос у великому місті

Вітаю, друзі!

Уявіть, що ви прийшли до величезного бізнес-центру. Вам потрібно вирішити три питання: замовити перепустку, забрати посилку і випити кави.

Уявіть, що рецепції (Reception) не існує.

  • Щоб отримати перепустку, вам кажуть: "Йдіть у кабінет 304 на 3-му поверсі, вхід з лівого крила".
  • За посилкою: "Це вам у підвал, двері №5, код на дверях 1234".
  • За кавою: "Кав'ярня на даху, але ліфт туди не їде, треба через пожежну драбину".

Це — архітектурне пекло. Ви (клієнт) змушені знати внутрішню структуру будівлі. А що, якщо відділ перепусток переїде в іншу кімнату? Вам доведеться вчити нову адресу.

У світі розробки це виглядає так: Ваш Frontend (React/Vue/Mobile) змушений знати: * Сервіс користувачів живе на localhost:3000 * Сервіс замовлень — на localhost:4000 * Сервіс оплат — на localhost:5000

Риторичне питання: А що буде, коли ми захочемо запустити три екземпляри сервісу замовлень, щоб впоратися з навантаженням? Як фронтенд дізнається, до якого з них стукати?

Ось тут на сцену виходить API Gateway. У нашому випадку — це Nginx.

Це ваша "Рецепція". Ви приходите на єдиний вхід (головні двері, порт 80), кажете "Мені потрібні замовлення", і рецепціоніст (Nginx) сам знає, куди вас направити. Вам байдуже, де саме фізично знаходиться сервіс.

Сьогодні ми навчимося будувати цей "єдиний вхід".


2. 🧠 Теоретична база (Що під капотом?)

Перш ніж писати код, давайте розберемося з логікою. Nginx тут виступає як Reverse Proxy (Зворотний проксі).

Що це означає?

  • Forward Proxy (Звичайний проксі): Ви ховаєтесь за ним, щоб вийти в інтернет (наприклад, щоб адмін не бачив, що ви сидите в Instagram).
  • Reverse Proxy: Сервери ховаються за ним, щоб клієнти не знали, яка там складна структура всередині.

Три кити конфігурації Nginx:

  1. Server Block (server { ... }): Це "будівля". Ми кажемо Nginx: "Слухай порт 80".
  2. Location (location /api { ... }): Це "вказівники в коридорі". Якщо людина йде по шляху /api/users, відправ її туди-то.
  3. Upstream (upstream backend { ... }): Це "група працівників". Ми можемо об'єднати кілька серверів під одним ім'ям.

⚠️ Що треба запам'ятати залізно:

Nginx не обробляє бізнес-логіку. Він не додає користувачів у базу. Він — регулювальник руху. Він отримує запит, дивиться на карту (конфіг) і пересилає запит далі (proxy_pass).


3. 🧪 Приклади: Від простого до реального

Давайте напишемо конфіг.

Приклад 1: "Привіт, світ!" (Найпростіший проксі)

Уявіть, що у нас є один мікросервіс (наприклад, на Node.js), який працює на порту 3000. Ми хочемо, щоб світ звертався до нього через стандартний порт 80.

Чого ви очікуєте від Nginx? Що він просто візьме все, що прийшло на порт 80, і кине на 3000.

server {
    listen 80;                 # 1. Слухаємо вхідні двері
    server_name myapp.com;

    location / {               # 2. Ловимо всі запити (корінь)
        proxy_pass http://localhost:3000; # 3. Перекидаємо на бекенд
    }
}

Пояснення: Коли ви вводите myapp.com, Nginx ловить запит і "прозоро" запитує дані у localhost:3000. Браузер думає, що спілкується з Nginx, він навіть не здогадується про існування порту 3000.


Приклад 2: Реальна маршрутизація мікросервісів

Тепер ускладнимо. У нас є: * Users Service (порт 3000) * Orders Service (порт 4000)

Ми хочемо, щоб: * myapp.com/users -> йшло на порт 3000 * myapp.com/orders -> йшло на порт 4000

server {
    listen 80;

    # Маршрут для користувачів
    location /users {
        proxy_pass http://localhost:3000;
    }

    # Маршрут для замовлень
    location /orders {
        proxy_pass http://localhost:4000;
    }
}

Питання: А що станеться, якщо я звернусь на myapp.com/banana? Відповідь: Nginx видасть помилку 404 (Not Found), тому що ми не прописали правило для /banana і не зробили дефолтного location /. Він діє строго за інструкцією!


Приклад 3: Load Balancing (Магія масштабування)

А тепер уявіть, що Orders Service (замовлення) ледве дихає від навантаження. Ми запустили його копію на порту 4001. Як змусити Nginx розкидати запити між 4000 і 4001?

Використовуємо upstream.

# Визначаємо групу серверів і даємо їй ім'я 'orders_backend'
upstream orders_backend {
    server localhost:4000;
    server localhost:4001;
}

server {
    listen 80;

    location /orders {
        # Тепер ми посилаємось не на IP, а на ім'я групи!
        proxy_pass http://orders_backend;
    }
}

Як це працює? За замовчуванням Nginx використовує алгоритм Round Robin (по колу). 1. Перший клієнт -> порт 4000. 2. Другий клієнт -> порт 4001. 3. Третій клієнт -> знову 4000.

Це і є балансування навантаження. І це робиться всього в 3 рядки коду! Хіба це не чудово?


4. 🛠 Практична частина

Тепер ваша черга. Не бійтеся помилятися — це найкращий спосіб вчитися.

Завдання 1: Налаштування "Воротаря"

У вас є сервіс на порту 8080. Напишіть блок server, який слухає порт 80 і перенаправляє всі запити з /api на цей сервіс.

Завдання 2: "Розділяй і володарюй"

Додайте до попереднього конфігу ще один маршрут. Усі запити, що починаються з /static (картинки, стилі), мають йти не на інший порт, а просто віддаватися з папки /var/www/html. (Підказка: тут замість proxy_pass використовується директива root або alias).

Завдання 3: Міні-кейс "Катастрофа"

У вас в upstream є два сервери. Один з них (на порту 5000) "впав" і вимкнувся. Що зробить Nginx, коли надійде запит? Спробуйте знайти відповідь: чи віддасть він користувачеві помилку, чи спробує інший сервер?

Завдання 4: Виправ помилку

Студент написав такий конфіг, але Nginx не запускається. Знайдіть дві помилки:

server {
    listen 80
    server_name test.com;

    location / {
        prox_pass http://localhost:3000;
    }
}

5. 💡 Мислення як у розробника

Як думають профі, коли налаштовують Gateway?

  1. Приховування деталей: Новачки часто намагаються "прокинути" все підряд. Досвідчений розробник знає: світ не має знати про мої порти 3000 чи 4000. Порти внутрішніх сервісів мають бути закриті фаєрволом, відкритий — тільки 80 (Nginx).

  2. Trailing Slash (Проблема слеша /): Це класика.

    • proxy_pass http://localhost:3000; (без слеша в кінці) — передає повний шлях.
    • proxy_pass http://localhost:3000/; (зі слешем) — обрізає частину шляху.
    • Порада: Завжди перевіряйте, чи не зникає частина URL при проксуванні.
  3. Безпека (SSL Termination): Замість того, щоб налаштовувати HTTPS на кожному з 10 мікросервісів, ми налаштовуємо його один раз на Nginx. Він розшифровує запит і всередині мережі передає його вже як звичайний HTTP. Це економить ресурси процесора на мікросервісах.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? Ми перетворили хаос із портів і адрес на струнку систему з єдиним входом.

Тепер ви вмієте: 1. Створювати єдину точку входу для всіх своїх сервісів. 2. Маршрутизувати трафік: "Користувачі — наліво, замовлення — направо". 3. Робити просте балансування навантаження, щоб ваші сервери не "лягли" у чорну п'ятницю.

Nginx — це клей, який тримає сучасний веб докупи.

Що далі?

Ви спитаєте: "Девід, а як це все запустити на моєму комп'ютері, не встановлюючи Nginx вручну?" Наступного разу ми поговоримо про Docker Compose — інструмент, який дозволить підняти всю цю архітектуру однією командою.

А поки — це був CS50, експериментуйте з конфігами! 🚀