JavaRush /Курси /Модуль 5. Spring /Лекція 249: Балансування навантаження в мікросервісах чер...

Лекція 249: Балансування навантаження в мікросервісах через API Gateway

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

Уявіть, що ваш мікросервіс обробляє запити з такою швидкістю, ніби він працює на паровій машині 1800-х років. А тим часом навантаження на ваш додаток зростає й кількість користувачів стрімко збільшується — саме так виглядає шлях до провалу. Балансування навантаження допомагає розподіляти вхідні запити між кількома екземплярами мікросервісу, щоб жоден з них не опинився перевантаженим. Це означає:

  • Підвищення відмовостійкості. Якщо один із екземплярів сервісу виходить з ладу, інші продовжують працювати.
  • Масштабованість. Ти можеш легко додати нові екземпляри сервісу, щоб справлятися з ростом навантаження.
  • Підвищення продуктивності. Запити обробляються швидше, бо навантаження рівномірно розподілене.

Балансування навантаження — це рятувальне коло, яке не дасть вашим мікросервісам потонути в морі запитів.


Як API Gateway здійснює балансування навантаження?

API Gateway, такий як Spring Cloud Gateway, може виконувати балансування навантаження кількома способами, включаючи механізми:

  1. Round Robin (круговий алгоритм): запити відправляються по черзі на кожну доступну точку (екземпляр сервісу). Наприклад, перший запит іде на Instance A, другий на Instance B і так далі, повертаючись до початку списку.
  2. Random (випадковий вибір): запит спрямовується на випадково обраний екземпляр сервісу.
  3. Weighted (з урахуванням ваги): розподіляє запити пропорційно вазі, яка призначена кожному екземпляру.

Додатково API Gateway може брати до уваги такі параметри, як затримка мережі або стан екземпляра сервісу.


Практична реалізація балансування навантаження

Переходимо від слів до справи! Давай реалізуємо приклад налаштування балансування навантаження через Spring Cloud Gateway.

Підготовка проєкту

1. Переконайтеся, що у вас уже встановлений Spring Boot і додані необхідні залежності для Spring Cloud Gateway. У pom.xml додайте такі залежності:


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2. Припустимо, що у вас уже налаштований Eureka Server, а ваші мікросервіси зареєстровані в ньому.

Налаштування Gateway для балансування

Тепер ми налаштуємо Spring Cloud Gateway для балансування запитів. Уявімо, що в нас є два екземпляри мікросервісу payment-service, які зареєстровані в Eureka з різними портами: 8081 і 8082.

Крок 1: Налаштування маршрутів у application.yml

Додаємо правила маршрутизації в конфігураційний файл application.yml для Gateway:


spring:
  cloud:
    gateway:
      routes:
        - id: payment-service-route
          uri: lb://payment-service # lb:// означає, що використовується система балансування навантаження
          predicates:
            - Path=/payments/** # Усі запити, що починаються з /payments, відправляються на payment-service

Зверніть увагу на використання lb:// в uri, яке вказує Spring Cloud Gateway використовувати систему балансування навантаження.

Крок 2: Реєстрація мікросервісів

Переконайтеся, що обидва екземпляри вашого сервісу payment-service зареєстровані в Eureka. Наприклад:

  • Перший екземпляр: http://localhost:8081
  • Другий екземпляр: http://localhost:8082

Перевірка працездатності

Запустіть Gateway і обидва екземпляри сервісу payment-service. Потім спробуйте надіслати кілька запитів:

curl http://localhost:8080/payments

API Gateway автоматично розподілить запити між екземплярами сервісу за алгоритмом Round Robin (за замовчуванням).


Налаштування кастомної стратегії балансування

Якщо потрібно використовувати іншу стратегію, це теж можливо! Spring Cloud Gateway використовує бібліотеку Spring Cloud LoadBalancer, яка підтримує різні алгоритми. Давайте змінимо стратегію на Random Load Balancing.

Крок 1: Додаємо кастомний LoadBalancer Bean

У конфігураційному класі CustomLoadBalancerConfiguration створюємо кастомний bean, який задає стратегію балансування:


import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.config.LoadBalancerConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
@LoadBalancerClient(value = "payment-service", configuration = CustomLoadBalancerConfiguration.class)
public class CustomLoadBalancerConfiguration {

    @Bean
    public ReactorServiceInstanceLoadBalancer loadBalancer(Environment environment,
                                                           LoadBalancerClient loadBalancerClient) {
        String serviceId = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClient, serviceId);
    }
}

Тут ми замінюємо алгоритм на Random, використовуючи RandomLoadBalancer. Тепер запити будуть спрямовуватись на випадковий екземпляр сервісу.

Моніторинг і аналіз навантаження

Після налаштування балансування важливо відслідковувати, як розподіляється навантаження. Для цього можна використовувати:

  1. Spring Boot Actuator: Метрики рівня gateway.requests показують статистику запитів через Gateway.
  2. Консоль Eureka: Eureka Dashboard дозволяє бачити статус екземплярів.
  3. Зовнішні інструменти моніторингу: Наприклад, Prometheus і Grafana для аналізу метрик і побудови графіків навантаження.

Помилки та особливості

При використанні балансування навантаження можуть виникати такі проблеми:

  • Якщо один із екземплярів сервісу виходить з ладу, але продовжує числитися в Eureka, запити до цього екземпляра призведуть до помилки. Це можна вирішити, налаштувавши Health Check в Eureka і виключаючи з переліку недоступні екземпляри.
  • Погане налаштування фільтрів або предикатів у Gateway може призвести до неправильної маршрутизації.
  • Не підготовлені сервери можуть відчувати нерівномірне навантаження, особливо якщо використовується політика Random.

Перегляньте документацію Spring Cloud Gateway для детальної настройки: Spring Cloud Gateway Documentation.


Висновок

Балансування навантаження — це ключовий інструмент для забезпечення відмовостійкості і покращення продуктивності мікросервісної системи. За допомогою Spring Cloud Gateway ти можеш легко реалізувати розподіл запитів між екземплярами своїх сервісів, використовуючи вбудовані механізми, такі як Round Robin або Random Load Balancing. Не забувай слідкувати за метриками та враховувати стан сервісів, щоб уникнути помилок і перевантажень.

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