Ось твій урок у стилі 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):
- API (Application Programming Interface): Це меню ресторану. Набір правил, за якими один сервіс може щось попросити в іншого.
- JSON: Це мова спілкування. Майже всі сервіси обмінюються даними у форматі JSON (схоже на словники в Python або об'єкти в JS).
- 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?"
🚀 Поради з практики:
- Ніколи не вір іншому сервісу. Завжди перевіряй, чи прийшли дані, і чи вони правильного формату.
- Використовуй Timeouts. Ніколи не роби запит без обмеження часу.
requests.get(url, timeout=5). Якщо за 5 сек немає відповіді — кидай трубку, не виси вічно. - Circuit Breaker (Запобіжник). Якщо сервіс помилився 10 разів поспіль, перестань йому дзвонити на 5 хвилин. Дай йому "охолонути".
6. 🧩 Підсумок
Сьогодні ми розбили моноліт на шматки і навчили їх дружити.
Що ви тепер вмієте? * Розумієте різницю між монолітом та мікросервісами. * Знаєте, що таке REST API (синхронно) та черги повідомлень (асинхронно). * Розумієте, що мережа може лагати, і ваш код має бути готовим до цього.
Наступного разу: Окей, у нас є 10 мікросервісів. Але як запустити їх всі одночасно і не зійти з розуму? Ми поговоримо про магічні коробки — Docker та Контейнеризацію. 📦
А поки що — це був CS50. Щасти вам!