JavaRush /Курси /Модуль 5. Spring /Лекція 163: Переваги мікросервісів: масштабованість, відм...

Лекція 163: Переваги мікросервісів: масштабованість, відмовостійкість, незалежність команд

Модуль 5. Spring
Рівень 11 , Лекція 2
Відкрита

Сьогодні поговоримо про три ключові переваги мікросервісів: масштабованість, відмовостійкість і незалежність команд. Ці три основи мікросервісів — головна причина, чому багато великих компаній (наприклад, Netflix і Amazon) переходять на мікросервісні архітектури.


Масштабованість: масштабуємо все на світі!

Масштабованість — це здатність твоєї системи "рости" (за кількістю користувачів або за навантаженням), зберігаючи продуктивність.

Припустимо, у тебе є магазин морозива. У спекотні дні черга зростає, і ти додаєш ще одну касу (або, якщо ти програміст, сервер). У мікросервісній архітектурі кожна каса (або служба) може масштабуватися незалежно від інших.

Горизонтальне масштабування

Мікросервіси дозволяють масштабувати тільки ті частини системи, які реально потребують більше ресурсів.

Наприклад, у тебе є сервіс логування і сервіс обробки замовлень. При цьому сервіс логування справляється чудово. Значить — просто залиш його в спокої. А сервіс обробки замовлень просто ламається під величезною кількістю запитів. Тоді підніми кілька додаткових інстансів лише для нього.

Приклад:


// Сервіс "Обробка замовлень"
@RestController
@RequestMapping("/orders")
public class OrderService {

    @GetMapping("/{id}")
    public Order getOrder(@PathVariable String id) {
        // Логіка для отримання замовлення з бази даних
        return orderRepository.findById(id);
    }
}

Подумай: якщо навантаження на цей "OrderService" зростає, ми можемо просто підняти більше таких інстансів і балансувати навантаження через, скажімо, Nginx або Kubernetes.

Гнучкість вибору технологій

У мікросервісах ти можеш вибрати іншу мову програмування або технологію для реалізації конкретного сервісу. Наприклад, для ML-обчислень використовуй Python, а для оброблювального REST API — Java.

Відмовостійкість: у тебе не впаде все одразу

Уяви ситуацію, коли падає монолітний додаток і разом з ним "помирає" весь функціонал. Користувачі сердяться, йдуть, і твій проєкт опиняється на межі загибелі. У мікросервісах же збій одного сервісу не вбиває всю систему.

Як мікросервіси забезпечують відмовостійкість? Кожен мікросервіс можна ізолювати, щоб збій в одному мінімально впливав на інших. Уявімо, що в нас є три сервіси:

  • OrderService (обробка замовлень)
  • PaymentService (обробка платежів)
  • NotificationService (повідомлення клієнтів)

Якщо NotificationService впаде, користувачі все одно можуть робити замовлення і оплачувати їх. Звісно, вони не отримають SMS-повідомлення, але основний функціонал збережеться.


Приклад коду з ізоляцією збоїв


// Приклад Circuit Breaker для відмовостійкості за допомогою Resilience4j
@Retry(name = "default", fallbackMethod = "fallbackResponse")
public String processOrder(String order) {
    // Основна логіка виконання
    return orderService.process(order);
}

public String fallbackResponse(String order, Throwable t) {
    return "Service is temporarily unavailable. Please try again later.";
}

Тут, якщо OrderService буде перевантажений, твій додаток може повернути fallback-відповідь, замість того щоб зависнути.

Події деградації функціоналу (Fallback)

Мікросервіси часто використовують концепцію деградації. Це означає, що у випадку збою одного сервісу інший може взяти на себе частину роботи або віддати "неідеальну", але робочу відповідь.

Приклад із життя: Google Maps. Якщо в тебе пропав доступ до інтернету, Google Maps все одно показує попередньо завантажені карти. Це приклад деградації функціоналу.

Відмовостійкість на практиці: реальний приклад

Uber використовує мікросервіси для забезпечення безперебійної роботи навіть при збоях. Якщо сервер маршрутизації (який визначає найкоротший шлях) виходить з ладу, користувач все одно може викликати машину — просто маршрут буде розрахований трохи пізніше.


Незалежність команд: менше головного болю для всіх

Коли ти працюєш у великій компанії, над одним додатком можуть працювати десятки, а то й сотні інженерів. Розробка моноліту в такій ситуації перетворюється на кошмар. Якщо команда A змінить один метод, команда B може раптово виявити сотні помилок у своїй частині коду.

Кожна команда працює над своїм сервісом, який незалежний від інших. Це зменшує кількість конфліктів і покращує продуктивність.


Приклад: Незалежність через API


// Команда А: розробляє "UsersService"
@RestController
@RequestMapping("/users")
public class UsersService {
    @GetMapping("/{id}")
    public User getUser(@PathVariable String id) {
        return userRepository.findById(id);
    }
}


// Команда Б: розробляє "OrdersService"
@RestController
@RequestMapping("/orders")
public class OrdersService {
    @GetMapping("/user/{userId}")
    public List<Order> getUserOrders(@PathVariable String userId) {
        return orderRepository.findByUserId(userId);
    }
}

Тут "OrdersService" знає тільки про API "UsersService", а не про його внутрішню реалізацію. Зміни всередині "UsersService" не зламають "OrdersService", якщо API залишається незмінним.


Підхід до програмування впливає на підходи в організації

Цікавий факт: мікросервіси не тільки змінюють архітектуру, а й модифікують організаційну структуру компанії. Ця ідея навіть має назву — "Закон Конвея" (Melvin Conway): структура твоєї системи повторюватиме структуру твоєї організації.

Хочеш незалежні мікросервіси? Дай своїм командам незалежність!

Незалежність на практиці: приклад Amazon

Amazon, як і Google, розбив свої команди на невеликі автономні групи, кожна з яких працює над своїм мікросервісом. Ці команди називаються "two-pizza teams" (команди на дві піци), бо команда має бути настільки маленькою, щоб її можна було нагодувати двома піцами.


Висновок

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

Важливо пам'ятати, що гнучкість мікросервісної архітектури вимагає відповідального підходу, особливо в питаннях моніторингу та підтримки. Без належного контролю за роботою сервісів неможливо забезпечити надійність системи в цілому.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ