Рубрики
Без рубрики

Введение в реактивную пружину

Почему Реактивное программирование Прошло 15 лет Там, где мы сейчас находимся… С пометкой java, программирование, информатика, дизайн.

Почему Реактивное программирование

Монолитные приложения Микросервисы
Запуск на сервере приложений Запуск в облаке
Не поддерживает распределенные системы Содержит распределенные системы

Каким должно быть ваше приложение:

  • Шкала, основанная на нагрузке

  • Эффективное использование ресурсов

  • Время отклика должно быть быстрее

Модель, которую мы имеем, – это поток на запрос, где для каждого запроса может быть поток для этого запроса.

Обработка Одновременных Запросов

  • Управляется server.tomcat.max-потоки свойство

  • Значение по умолчанию – 200 подключений

  • Мы можем использовать application.properties или приложение.файл yml для переопределения значения

  • Каждый поток будет занимать некоторое количество памяти

  • Общий размер стека составляет 1 МБ

  • Чем больше размер пула потоков, тем выше потребление

  • При меньшем объеме доступной памяти наше приложение будет работать плохо.

Как это делается сегодня

  • Нагрузка сбалансирована с помощью горизонтального масштабирования и может быть достигнута с помощью некоторой оркестровки контейнеров

  • Но нам нужно создать несколько экземпляров, и это увеличит затраты для организации

Традиционные API-интерфейсы Rest

  • Отлично работает для многих случаев использования

  • Многие API будут в будущем также с таким же дизайном

  • Это не устарело

  • Также нет необходимости переводить традиционный Rest API на новую модель, так как у него есть свои преимущества

Как работает традиционный API Rest

// simple rest api end point
@GetMapping("/getCatalog")
    public ResponseMessage getCatalog() {
        return movieFeignClient.listAllMovies();
    }
  • API императивного стиля

    • Подход сверху вниз
  • Блокирующий и синхронный

  • Блокировка означает, что когда пользователь отправляет запрос на сервер и данные должны быть извлечены из базы данных, поток обрабатывает запрос и выполняет вызов базы данных. До тех пор, пока ответ не будет получен, поток ничего не будет делать и будет находиться в состоянии блокировки, что неэффективно.

  • Синхронный означает, что клиенту необходимо дождаться возврата вызова API, прежде чем продолжить выполнение кода, что может привести к снижению производительности или проблемам, связанным с задержкой.

  • Так что мы можем сделать

    • Нужно совершать звонки асинхронно, не блокируя
    • У нас могут быть обратные вызовы и фьючерсы

Обратные вызовы:

  • Сложный

  • Нет возвращаемого значения

  • Код трудно читать и поддерживать

  • Ведет к Обратному вызову аду

Будущее:

  • Еще одна альтернатива написанию асинхронного кода на java

  • Возвращаемый экземпляр функции

  • Трудно составить несколько асинхронных операций

Завершаемое будущее:

  • Поддерживает API-интерфейсы функционального стиля

  • Простые в составлении асинхронные операции

  • Не очень подходит асинхронный вызов с несколькими элементами

Традиционный Rest API не имеет функции обратного давления, которая сообщает базе данных, предположим, если один из наших запросов отвечает огромным объемом данных, которые не нужны клиенту, тогда мы можем попросить базу данных замедлить процесс, например, создать противодавление.

В общем

  • Нам нужно разработать асинхронный и неблокирующий API

  • Отойти от модели потока по запросу

  • Используйте меньше потоков

  • Совместимость с обратным давлением

Реактивное программирование

  • Асинхронный и неблокирующий

  • Данные будут передаваться как Управляемые событиями/сообщениями поток

  • Функциональный код стиля

  • Противодавление на поток данных

  • Не ждать и блокировать

Поток данных как поток, управляемый событиями

  • Одно событие или сообщение для каждого результата из источника данных (БД, внешних служб и т.д.)

  • Одно событие или сообщение о завершении или ошибке

    • Далее(пункт) -> События потока данных
    • Неполный() -> Событие завершения/успеха
    • onError() -> Событие ошибки

Функциональный Код Стиля

  • Легко работать с лямбдами

  • Аналогично API потоков

Спецификация реактивного пара

  • Спецификация или правила для реактивного потока

  • Издатель

  • Подписчик

  • Подписка

  • Процессор

Издатель
  • Представляет источник данных
public interface Publisher {
    public void subscribe(Subscriber s);
}

Подписчик
public interface Subscriber {
    public void onSubscribe(Subscription s);
    public void onNext(T t);
    public void onError(Throwable t);
    public void onComplete();
}

Подписка
public interface Subscription {
    public void request(long n);
    public void cancel();
}

Поток событий Издателя/Подписчика

  • Подписчик вызывает метод subscribe() и передает экземпляр Подписчика в качестве входных данных Издателю

  • Издатель подтверждает, отправляя подписку

  • Абонент предоставляет запрос(n) способ получения данных

  • Издатель создает при следующем(данных) событии для указанного n раз и при успешном завершении создает неполный() событие

  • Таким образом, абонент предоставляет количество данных, которые говорят о функции обратного давления

Процессор

  • Нравится комбинация как подписчика, так и издателя
public interface Processor extends Subscriber, Publisher {

}

Реактивные библиотеки

  • RxJava

  • Реактор

  • Класс потока – JDK 9

Проектный реактор

активная зона реактора

  • Основная библиотека проектного реактора

  • Реализация спецификации реактивных потоков

  • поток и моно

  • поток представляет от 0 до n элементов

  • mono представляет от 0 до 1 элементов

Поток

Изображение взято из проекта Реактор

// flux

Flux.just("Spring", "Spring Boot", "Reactive Spring Boot")
.map(s -> s.concat("flux"))
.subscribe(System.out::println);

Моно

Изображение взято из проекта Реактор

// mono

Mono.just("Spring")
.map(s -> s.concat("flux"))
.subscribe(System.out::println);

Я включил некоторые практические примеры flux и mono в репозиторий github, и еще есть примеры, которые будут добавлены и будут обновлены. Пожалуйста, посмотрите и прокомментируйте любые ошибки, которые я допустил и которые необходимо исправить.

Рохитв07/Реактивная пружина

Реактивное программирование весной

Реактивное программирование весной

Почему Реактивное программирование

Монолитные приложения Микросервисы
Запуск на сервере приложений Запуск в облаке
Не поддерживает распределенные системы Содержит распределенные системы

Каким должно быть ваше приложение:

  • Шкала, основанная на нагрузке

  • Эффективное использование ресурсов

  • Время отклика должно быть быстрее

Модель, которую мы имеем, – это поток на запрос, где для каждого запроса может быть поток для этого запроса.

Обработка Одновременных Запросов

  • Управляется server.tomcat.max-потоки свойство

  • Значение по умолчанию – 200 подключений

  • Мы можем использовать application.properties или приложение.файл yml для переопределения значения

  • Каждый поток будет занимать некоторое количество памяти

  • Общий размер стека составляет 1 МБ

  • Чем больше размер пула потоков, тем выше потребление

  • При меньшем объеме доступной памяти наше приложение будет работать плохо.

Как это делается сегодня

  • Нагрузка сбалансирована с помощью горизонтального масштабирования и может быть достигнута с помощью некоторой оркестровки контейнеров

  • Но нам нужно создавать…

Оригинал: “https://dev.to/rohithv07/introduction-to-reactive-spring-40nm”