Модуль 25

Інтеграція з мікросервісами

Ось твій урок у стилі CS50! 🚀


🎓 Урок: Інтеграція з мікросервісами

Привіт, світе! Мене звати [Твоє Ім'я], і це... CS50: Microservices Edition.

Сьогодні ми виходимо за межі "мого коду на моєму комп'ютері". Ми поговоримо про те, як змусити програми спілкуватися між собою.


1. 🔥 Вступ: Чому "один гігант" — це погано?

Уявіть, що ви будуєте Uber або Glovo.

На початку ви пишете одну велику програму. У ній є все: реєстрація користувачів, обробка платежів, мапа з кур'єрами, відгуки. Це називається Моноліт.

Уявіть це як гігантську кухню ресторану, де 50 кухарів товчуться в одній кімнаті. * Якщо один кухар розіб'є банку з олією, послизнуться всі. * Якщо зламається піч для піци, суші-майстер теж не зможе працювати, бо кухня закривається на ремонт.

Питання до вас:

Що станеться з вашим додатком Uber, якщо модуль "Відгуки" зависне через помилку в коді? Спойлер: Швидше за все, впаде весь додаток, і ніхто не зможе викликати таксі.

Рішення? Мікросервіси.

Ми розбиваємо цю кухню на фуд-корт. * Піцерія — окремо. * Суші — окремо. * Каса — окремо.

Якщо в піцерії згоріла піч, суші все ще продаються!

Але тут виникає головна проблема: як касир (один сервіс) має сказати кухарю (іншому сервісу), що замовлення прийнято? Вони більше не в одній кімнаті! Їм треба інтегруватися.


2. 🧠 Теоретична база: Як вони "розмовляють"?

Коли ми інтегруємо мікросервіси, ми фактично вчимо їх дзвонити один одному або писати листи.

Два головні способи спілкування:

1. Синхронний ("Телефонний дзвінок") 📞

Ви (Сервіс А) дзвоните другу (Сервіс Б) і кажете: "Дай мені дані користувача ID 42". Ви тримаєте слухавку і чекаєте, поки він відповість. * Технологія: Найчастіше це HTTP / REST API. * Плюс: Просто, результат миттєвий. * Мінус: Якщо друг не бере слухавку, ви висите на лінії і нічого не робите.

2. Асинхронний ("СМС або Пошта") ✉️

Ви (Сервіс А) кидаєте повідомлення в скриньку: "Створіть рахунок для замовлення #101". Ви не чекаєте відповіді і йдете працювати далі. * Технологія: Message Brokers (RabbitMQ, Kafka). * Плюс: Якщо друг зайнятий, він прочитає повідомлення пізніше. Ваша система не гальмує. * Мінус: Складніше налаштувати. Ви не знаєте миттєво, чи все пройшло успішно.

🔑 Що треба запам'ятати (The Big Picture):

  1. API (Application Programming Interface): Це меню ресторану. Набір правил, за якими один сервіс може щось попросити в іншого.
  2. JSON: Це мова спілкування. Майже всі сервіси обмінюються даними у форматі JSON (схоже на словники в Python або об'єкти в JS).
  3. Latency (Затримка): Звернення до функції всередині коду займає 0.0001 сек. Звернення до іншого сервісу через мережу — 0.05 сек. Це в 500 разів повільніше. Пам'ятайте про це!

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

Давайте подивимось на код. Уявимо, що ми пишемо на Python.

Приклад 1: Простий запит (Синхронний)

У нас є Сервіс Замовлень. Йому треба дізнатися ціну товару у Сервісу Складу.

Питання: Що ми очікуємо отримати, якщо товар існує? А якщо ні?

import requests # Бібліотека для HTTP запитів

def get_product_price(product_id):
    # Ми "дзвонимо" на інший сервіс
    try:
        response = requests.get(f"http://warehouse-service/api/products/{product_id}")

        # Перевіряємо, чи "взяли слухавку" (код 200 означає ОК)
        if response.status_code == 200:
            data = response.json() # Розпаковуємо відповідь
            return data['price']
        elif response.status_code == 404:
            return "Товар не знайдено"
        else:
            return "Помилка на складі"

    except requests.exceptions.ConnectionError:
        return "Сервіс складу недоступний! (Паніка? Ні, обробка помилок)"

# Виклик
price = get_product_price(101)
print(f"Ціна: {price}")

Чому це так працює? Ми використовуємо протокол HTTP (той самий, що вантажить сайти в браузері), щоб передати дані між програмами.


Приклад 2: Реальний сценарій (Ланцюжок викликів)

Уявіть процес купівлі квитка в кіно. 1. Сервіс Каси перевіряє місця. 2. Сервіс Банку списує гроші. 3. Сервіс Сповіщень відправляє квиток на пошту.

Якщо ми зробимо це послідовно (синхронно):

Каса -> чекає -> Банк -> чекає -> Сповіщення -> Клієнт.

Це довго. Клієнт дивиться на кружечок завантаження 10 секунд.

Як роблять профі? Сервіс Каси каже: "Місце заброньовано, гроші списано". А квиток на пошту відправиться асинхронно (у фоні).

# Псевдокод асинхронної події
def buy_ticket(user_id, movie_id):
    # 1. Бронюємо місце (синхронно, бо це критично)
    booking = requests.post("http://booking-service/book", json={...})

    if booking.status_code == 200:
        # 2. Кидаємо повідомлення в чергу для відправки листа
        # Ми НЕ чекаємо, поки лист відправиться
        message_queue.publish("email_topic", {
            "to": user_id, 
            "msg": "Ваш квиток тут!"
        })
        return "Успіх! Перевірте пошту через хвилину."

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

Час забруднити руки кодом (або псевдокодом).

Завдання 1: "Hello, Neighbor!" Напиши функцію, яка робить GET-запит до публічного API (наприклад, https://api.coindesk.com/v1/bpi/currentprice.json) і виводить поточну ціну Біткоїна. Мета: Навчитися робити базовий "дзвінок".

Завдання 2: "Абонент поза зоною" Зміни URL у своєму коді на неіснуючий (наприклад, https://fake-url-xyz.com). Додай блок try-except (або try-catch), щоб програма не впала з червоним текстом помилки, а вивела гарне повідомлення: "На жаль, сервер крипти зараз відпочиває". Мета: Зрозуміти важливість обробки помилок мережі.

Завдання 3: Міні-кейс "Інтернет-магазин" У тебе є список order = {"item_id": 5, "quantity": 2}. Напиши логіку (на папері або в коді): 1. Запитати у InventoryService чи є item_id: 5 у кількості 2 шт. 2. ЯКЩО так -> звернутися до PaymentService для оплати. 3. ЯКЩО ні -> повернути користувачеві "Немає на складі".

Завдання 4: "А що, якщо..." (Мисленнєвий експеримент) У завданні 3 ми списали гроші, але раптом після цього наш сервер вимкнувся, і ми не встигли показати користувачеві "Успіх". Гроші зняли, а замовлення не створили. Як би ти вирішив цю проблему? (Підказка: Транзакції або повернення коштів).


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

Як думає новачок?

"Я напишу запит, сервер відповість, я отримаю дані. Все просто."

Як думає Senior Engineer?

"Мережа — ненадійна. Сервер може впасти. Відповідь може йти 30 секунд. Що робити моєму коду, якщо інший сервіс відповість сміттям замість JSON?"

🚀 Поради з практики:

  1. Ніколи не вір іншому сервісу. Завжди перевіряй, чи прийшли дані, і чи вони правильного формату.
  2. Використовуй Timeouts. Ніколи не роби запит без обмеження часу. requests.get(url, timeout=5). Якщо за 5 сек немає відповіді — кидай трубку, не виси вічно.
  3. Circuit Breaker (Запобіжник). Якщо сервіс помилився 10 разів поспіль, перестань йому дзвонити на 5 хвилин. Дай йому "охолонути".

6. 🧩 Підсумок

Сьогодні ми розбили моноліт на шматки і навчили їх дружити.

Що ви тепер вмієте? * Розумієте різницю між монолітом та мікросервісами. * Знаєте, що таке REST API (синхронно) та черги повідомлень (асинхронно). * Розумієте, що мережа може лагати, і ваш код має бути готовим до цього.

Наступного разу: Окей, у нас є 10 мікросервісів. Але як запустити їх всі одночасно і не зійти з розуму? Ми поговоримо про магічні коробки — Docker та Контейнеризацію. 📦

А поки що — це був CS50. Щасти вам!