webflux spring что это

WebSockets и Spring WebFlux

Все мы знаем вебсокеты, любим или не очень и можем написать их со Spring MVC.

А что на счет реактивного приложения?

В этой статье будет рассмотрено как создать вебсокеты с помощью Spring WebFlux.

Для создания проекта использовалась страница start.spring.io с зависимостью Reactive Web.

Как сконфигурировать вебсокет

Начнем с конфигурации, чтобы наглядно продемонтрировать почему нам нужен тот или иной компонет.

Первое что нужно сделать это написать конфигурацию для реактивного вебсокета.

Для этого нужно два бина: HandlerMapping и HandlerAdapter.

HandlerAdapter создается довольно таки легко:

Зачем нужен этот бин?

Адаптер внутри себя инициализирует вебсокет сервис и использует (еще не написанную нами) имплементацию WebSocketHandler. Другими словами, этот бин включает вебсокет в Spring WebFlux.

Следующий бин это HandlerMapping. С помощью него мы можем настроить url и отвечающий за него WebSocketHandler, а так же порядок инициализации бина. Спринг будет знать как настоить нужный url и как его обрабатывать благодяря этой конфигурации. Наш url будет выглядить так http://localhost:8080/push, так как ниже мы настраиваем путь как /push.

Конечно можно создавать сколько угодно url и WebSocketHandler.

Теперь можно создать имплементацию WebSocketHandler. С этим классом мы можем обрабатывать объект WebSocketSession, другими словами читать и отправлять сообщения.

На данный момент мы оставим Mono.empty(), но не волнуйтесь, ниже будет полноценная имплементация.

Полный код конфигурации.

Как прочитать сообщение?

Логика чтения может быть реализована в имплементации интерфейса WebSocketHandler.

Нам нужно использовать объект WebSocketSession и просто вызывать метод receive(), чтобы получить стрим и обработать его.

Как отправить сообщение?

Перед тем как продолжить изменять WebSocketHandler нужно создать какой-то простенький дата класс, который мы будем слать клиенту.

Так же нужно создать сервис, который сможет возвращать ивенты в виде реактивного стрима (как требует WebSocketSession).

Главное: нужно добавлсять новые ивенты в стрим.

Так что теперь может создать наш интерфейс:

Имплементация будет использовать EmitterProcessor, который подходит под все наши требования. Этот процессор может потреблять наши ивенты и раздавать подписчикам.

Так же можно использовать метод replay(int), который кэширует указанное количество элементов и возвращает новым подписчикам.

Отправка сообщений будет выглядить вот так:

Как видно из кода выше, перед тем как отправить объект клиенту, его нужно сконвертировать в json. Spring WebFlux не предоставляет механизм для десериализации объекта в json для вебсокетов.

В примере используется Jackson, а именно ObjectMapper#writeValueAsString, так что на выходе мы имеем json строку.

Теперь можно объединить чтение и отправку в DefaultWebSocketHandler.

Event generator

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

Не забываем включить Scheduler в приложении.

Клиент

Для клиента будет использоваться Angular.

Здесь мы используем rxjs websockets.

Чтобы увидеть наши сообщения надо обновить app.component.html.

Теперь можно запустить приложение и открыть в браузере localhost:4200.

Рекомендации как обезопасить вебсокеты

Выводы

В статье показана базовые кофигурация, чтение и отправка сообщений используя реактивные вебсокеты, которое было рассмотрено на примере демопроекта. Так же можно увидеть, что реализация упирается в знание Project Reactor.

Источник

Spring WebFlux: Реактивное программирование веб-сервисов

Особенности: преимущества и недостатки

Модуль WebFlux появился в 5й версии фреймворка Spring. Этот микрофреймворк является альтернативой Spring MVC и отражает собой реактивный подход для написания веб-сервисов. В основе WebFlux лежит библиотека Project Reactor, позволяющая легко запрограммировать неблокирующие (асинхронные) потоки (streams), работающие с вводом/выводом данных.

Следует учесть, что WebFlux для работы требуется встроенный в Spring сервер Netty. Встроенные Tomcat и Jetty не подходят. Следующая диаграмма иллюстрирует особенности окружения, в котором работает WebFlux [1].

График внизу демонстрирует преимущество в производительности реактивных веб-сервисов [2] по сравнению с обычными, блокирующими. При загруженности сервера в 300 и более пользователей Netty начинает превосходить Tomcat по количеству одновременно обрабатываемых запросов. При предельной загруженности сервера в реактивном режиме может одновременно обслуживаться в 2 раза больше пользователей. По другим источникам преимущество не так внушительно, но заметно. Наибольший эффект реактивное программирование дает при вертикальном масштабировании.

Важная особенность реактивности еще в том, что она дает слабую связность. Например, если между клиентом и сервисом происходит разрыв соединения, оно воссоздается при восстановлении Интернет. Ограничения во времени не требуется, так-как соединение происходит для отдельного потока, не влияющего на другие. Но при этом реактивный подход должен быть реализован на обеих сторонах.

Программировать приложение с множеством неблокирующих потоков достаточно непривычная задача. Требуется особый подход и стиль программирования, основанный на лямбда-выражениях с использованием реактивных библиотек. Библиотека Project Reactor, входящая в WebFlux, отличается от реактивной библиотеки RxJava (реализованной, например, в Android) тем, что больше подходит для бэкэнда. Например, устранены некоторые проблемы, которые могут вызвать нехватку памяти.

К неудобствам реактивного программирования следует отнести более ограниченный инструментарий для работы с реляционными БД. Например, JPA-библиотеки Hibernate и EclipseLink не поддерживают реактивность. Невозможно в Java описывать сложные связи между объектами, как это делается обычно тегами @Entity, @OneToMany, @ManyToMany, @JoinTable и т.д.. Не получится программно описать ограничение целостности таблиц. Хотя это придает большую гибкость используемой БД. Для привязки классов к таблицам достаточно тегов @Table и @Column. Языки JPQL (HQL) не годятся для реактивных запросов к БД. Но при этом доступен нативный SQL. Вместо JDBC потребуется R2DBC. Об этом чуть позже.

Простейший пример реактивного REST-сервиса и REST-клиента

Для разработки реактивного сервиса достаточно в pom.xml добавить модуль spring-boot-starter-webflux, вместо обычного spring-boot-starter-web в Spring MVC.

Кодирование REST сервисов и их клиентов в Spring WebFlux может полностью совпадать со Spring MVC. Отличие только в определении возвратов. На выходе методов в WebFlux мы добавляем Mono (или в особых случаях Flux, когда требуется последовательно в одном потоке передать несколько объектов). Например, метод sendSms контроллера SmsController

Читайте также:  Что такое код группы в покемон го

обращается к методу sendSms сервиса SmsService:

Цепочка методов smsClient.post().bodyValue() может заканчиваться методом retrieve().bodyToMono(), если не требуется дальнейшая обработка и преобразование объектов передаваемых клиентом. Иначе, как в примере, требуется exchange().flatMap( ).

Реактивный клиент в Spring определяется только через WebClient. Шаблон RestTemplate (из Spring MVC) не подходит. Подробнее о реактивных REST-сервисах здесь [3].

Работа с реактивными реляционными БД: Особенности

Для подключения реактивных реляционных библиотек через Maven в pom.xml потребуется добавить две зависимости. Пример для PostgreSQL.

org.springframework.data
spring-data-r2dbc

io.r2dbc
r2dbc-postgresql

Приятным сюрпризом при переходе с JPA на R2DBC будет уменьшение размера, собираемого джарника приложения, на пару десятков мегабайт. Зависимость spring-boot-starter-data-jpa тянет множество библиотек, требуемых для поддержки JPA.

Вот как выглядит описание реактивного CRUD-репозитария

В примере объекты, возвращаемые запросами к БД, определяются классом Client приблизительно такого вида:

Поля имеют примитивные типы. Мы не описываем вложенные объекты User или PersonData. К этим объектам потребуется обращаться отдельными запросами зная userId или personId. Для ускорения, конечно лучше использовать один объединенный SELECT с JOIN из нативного SQL. Для JPA в подобных случаях (когда объекты не требуются) используют lazy loading.

Источник

Реактивное программирование со Spring, часть 3 WebFlux

1. Введение в Spring WebFlux

WebFlux был представлен как часть Spring Framework 5.0. В отличие от Spring MVC, он не требует Servlet API. Он полностью асинхронный и неблокирующий, реализует спецификацию Reactive Streams через проект Reactor (см. предыдущий пост в блоге ).

WebFlux требует Reactor в качестве основной зависимости, но он также может взаимодействовать с другими реактивными библиотеками через Reactive Streams.

1.1 Модели программирования

Spring WebFlux поддерживает две разные модели программирования: на основе аннотаций и функциональную.

1.1.1 Аннотированные контроллеры

Если вы работали со Spring MVC, модель на основе аннотаций будет выглядеть довольно знакомой, поскольку в ней используются те же аннотации из веб-модуля Spring, что и в Spring MVC. Основное отличие состоит в том, что теперь методы возвращают реактивные типы Mono и Flux. См. Следующий пример RestController с использованием модели на основе аннотаций:

Некоторые пояснения к функциям, использованным в примере:

map функция используется для преобразования элемента, испускаемого Mono, применяя функцию синхронной к нему.

flatMap функция используется для преобразования элемент, испускаемый Mono асинхронно, возвращая значение, излучаемого другим Mono.

1.1.2 Функциональные конечные точки

HandlerFunctions используются для генерации ответа на данный запрос:

RouterFunction используется для маршрутизации запросов к HandlerFunctions:

Продолжая с тем же примером ученика, мы получим что-то вроде следующего, используя функциональный стиль.

Некоторые пояснения к функциям, использованным в примере:

Сравнивая две модели, мы видим, что:

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

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

1.2 Поддержка сервера

WebFlux работает в средах выполнения, отличных от сервлетов, таких как Netty и Undertow (неблокирующий режим), а также в средах выполнения сервлетов 3.1+, таких как Tomcat и Jetty.

По умолчанию стартер Spring Boot WebFlux использует Netty, но его легко переключить, изменив зависимости Maven или Gradle.

Например, чтобы переключиться на Tomcat, просто исключите spring-boot-starter-netty из зависимости spring-boot-starter-webflux и добавьте spring-boot-starter-tomcat:

1.3 Конфигурация

Spring Boot обеспечивает автоматическую настройку Spring WebFlux, которая хорошо работает в общих случаях. Если вам нужен полный контроль над конфигурацией WebFlux, можно использовать аннотацию @EnableWebFlux (эта аннотация также потребуется в простом приложении Spring для импорта конфигурации Spring WebFlux).

Если вы хотите сохранить конфигурацию Spring Boot WebFlux и просто добавить дополнительную конфигурацию WebFlux, вы можете добавить свой собственный класс @Configuration типа WebFluxConfigurer (но без @EnableWebFlux).

Подробные сведения и примеры см. в документации по конфигурации WebFlux.

2. Защита ваших конечных точек

Чтобы получить поддержку Spring Security WebFlux, сначала добавьте в свой проект зависимость spring-boot-starter-security. Теперь вы можете включить его, добавив @EnableWebFluxSecurity аннотацию в свой класс Configuration (доступно с Spring Security 5.0).

В следующем упрощенном примере будет добавлена ​​поддержка двух пользователей, один с ролью USER, а другой с ролью ADMIN, принудительно применить базовую аутентификацию HTTP и потребовать роль ADMIN для любого доступа к пути /student/admin:

Также можно защитить метод, а не путь, сначала добавив аннотацию @EnableReactiveMethodSecurity к вашей конфигурации:

А затем добавляем @PreAuthorize аннотацию к защищаемым методам. Например, мы можем захотеть, чтобы наши методы POST, PUT и DELETE были доступны только для роли ADMIN. Затем к этим методам можно применить аннотацию PreAuthorize, например:

Spring Security предлагает дополнительную поддержку, связанную с приложениями WebFlux, например защиту CSRF, интеграцию OAuth2 и реактивную аутентификацию X.509. Для получения дополнительной информации прочтите следующий раздел в документации Spring Security: Реактивные приложения

3. Веб-клиент

Spring WebFlux также включает реактивный, полностью неблокирующий веб-клиент. У него есть функциональный, свободный API, основанный на Reactor.

Давайте рассмотрим (еще раз) упрощенный пример того, как WebClient можно использовать для запроса нашего StudentController:

4. Тестирование

Для тестирования вашего реактивного веб-приложения WebFlux предлагает WebTestClient, который поставляется с API, аналогичным WebClient.

Давайте посмотрим, как мы можем протестировать наш StudentController с помощью WebTestClient:

5. WEBSOCKETS и RSOCKET

5.1 Веб-сокеты

В Spring 5 WebSockets также получает дополнительные реактивные возможности. Чтобы создать сервер WebSocket, вы можете создать реализацию WebSocketHandler интерфейса, которая содержит следующий метод:

WebSocketSession имеет методы, определенные для обработки входящих и исходящих потоков:

Читайте также:  монк фрут сахарозаменитель что это

Spring WebFlux также предоставляет WebSocketClient реализации для Reactor Netty, Tomcat, Jetty, Undertow и стандартной Java.

Для получения дополнительной информации прочтите следующую главу в документации Spring’s Web on Reactive Stack: WebSockets

5.2 RSOCKET

А для получения дополнительной информации о поддержке Spring Framework протокола RSocket

6. Подводя итог…

Источник

Spring MVC vs Spring WebFlux. Что лучше? Объясняем на пингвинах

Существует множество способов реализации REST-API. Большой популярностью пользуется Spring MVC на основе блокирующих вызовов, но все чаще попадаются проекты, использующие WebFlux на неблокирующих вызовах. Меня зовут Альберт Фатхудинов. Я Java-разработчик Технократии. В этой статье буду разбираться, какой из этих двух фреймворков работает лучше.

Технологии, которые использовали

Дисклеймер, в котором перечислим технологии, которые применялись в эксперименте:

Apache JMeter — для нагрузочного тестирования

VisualVm — для профилирования

MongoDb — NoSql База данных

PostgreSql — реляционная база данных

Netty — серверная среда неблокирующего ввода/вывода для разработки сетевых приложений

Apache Tomcat — контейнер сервлетов

Spring MVC — Фреймворк, обеспечивает архитектуру паттерна MVC при помощи слабо связанных готовых компонентов

Spring WebFlux — фреймворк, реализующий парадигму реактивного программирования, добавлен в Spring 5+

На этом дисклеймер закончился. Поехали!

Архитектура тестового приложения

Представим абстрактного пингвина, которого зовут Шкипер. Он хочет узнать о своих последних штрафах, налогах и коммунальных платежах. Для этого он использует NotificationService. Но есть несколько проблем:

Время ответа БД PostgreSql и MongoDb — от 30 мс до 200 мс (специально занижал производительность БД неправильными индексами и большой вложенностью Json. Также добавил по 1 млн записей в каждую БД)

Внутреннюю реализацию сервиса(MVC Tomcat) можно посмотреть здесь.

Тестовые запросы

Время ответа от сервиса входит в диапазон от 1 до 3 секунд.

Такое время ответа не устраивает как пингвинов, так и нас. Нужно разобраться в чем же проблема.

Блокирующие вызовы

Без нагрузки Tomcat, который по умолчанию используется в starter-web Спринга, создаёт 10 потоков http exec. При нагрузке же он может масштабироваться до 200 потоков. В моем примере томкат масштабировался примерно до 170 потоков при единовременной нагрузке в 1000 пользователей.

Без нагрузки Под нагрузкой. Огромное количество потоков крадут друг у друга процессорное время. Нецелесообразное использование мощностей процессора

Нагрузочное тестирование показало, что 1000 одновременных запросов сервис обработал за 2 минуты 38 сек, количество ошибок составило 23.1 % от общего количества запросов при пропускной способности в 6.3 запроса в секунду.

Сводная таблица по нагрузочному тестированию

Модель Tomcat основана на блокирующих вызовах. Когда поток обращается к БД или удаленному сервису, он блокируется и, пока не будет получен ответ, так и будет находится в заблокированном состоянии.

Как ведет себя поток в стандартном MVC приложении на Tomcat

WEBFLUX Неблокирующие вызовы

Перейдем к другой реализации. Что за такой зверь WebFlux? Это микрофреймворк, который представляет полностью асинхронный и неблокирующий веб-стек, который позволяет обрабатывать большее количество одновременных запросов по сравнению с стандартным MVC.

Reactive streams

Это стандартный способ асинхронной обработки в потоковом стиле. В него входят следующие интерфейсы: subscriber, publisher, subscription и processor.

Принцип работы reactive streams:

Subscriber подписывается на publisher(subscribe()), но общаться с publisher будет через subscription.

Subscription получает данные от publisher и отгружает их в подписчика (onNext(data)).

C помощью методов onError() и onComplete() Subscription принимает от Subscriber информацию о том, сколько данных он хочет получить от publisher через метод request(n). Старый добрый паттерн Наблюдатель, в лучшей реализации.

Реактивный сервер?

Да! Мы преобразуем наш сервис уведомления о штрафах в реактивное приложение. Для начала представим реактивную архитектуру:

Архитектура реактивного приложения

Приложение состоит из 5 составляющих:

HTTP Server. В нашем случае Netty, так как WebFlux по умолчанию предоставляет данный сервер.

Реактивный адаптер. Интересно и зачем же здесь адаптер? Все очень просто. Netty и WebFlux не совместимы, поэтому здесь и нужен адаптер.

Репозиторий для коннекта с БД.

И последнее, все элементы архитектуры начинают общаться с помощью реактивного типа FLUX

Теперь подробнее про каждую часть.

NETTY

NETTY — асинхронная среда сетевых приложений, управляемая событиями. На входе у Netty в бесконечном цикле крутится поток. За счет каналов и селекторов он перенаправляет входящие запросы во входящие буферы и делегирует обработку запросов выделенному пулу асинхронных потоков.

Есть очередь событий и event loop, который их обрабатывает и делегирует пулу асинхронных потоков. В то же время происходит регистрация Callback-а. Он вызывается для отгрузки данных, после завершения обработки асинхронным пулом потоков.

Как же это выглядит в приложении? А вот как:

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

Reactive Adapter

Вернемся к реактивному адаптеру. Я упомянул, что Netty и WebFlux несовместимы. Вот тут и появляется Reactor IPC.

Это расширение, позволяющее интегрироваться с различными платформами и системами. Когда запрос поступает на Netty, он обрабатывается ChannelOperations, затем вызывается цепочка вызовов, которая достигает Dispatcher handler, а затем запрос достигает контроллера.

Затем на основе publisher выстраивается поток, достигающий ChannelOperations. Следом в ChannelOperataions вызывается метод subscribe. Только в этот момент поток начинает свою работу.

Реактивные типы

К реактивным типам относятся Mono и Flux. Они имплементируют интерфейс publisher, т.е являются источниками данных.

Если нам нужно отгружать пользователю от 0 до N объектов используем FLUX

Если же нужно отгружать от 0 до 1 элементов используем MONO

Если мы ничего не хотим отгружать используем MONO

Publisher делят на два вида HOT и COLD.

Приведу аналогию: фильм, запущенный на Netflix с самого начала — это cold publisher, а стрим на twitch, в который мы ворвались на середине, — HOT. Cold publisher начинает отгружать данные, когда на него подписываются с самого начала, а Hot publisher отгружает данные тем, кто подписался с момента остановки отгрузки данных.

Читайте также:  какие семьи являются неполными

Элемент Processor импелементирует интерфейс subscriber и publisher, используется для обработки данных Mono или Flux для того, чтобы не обрывать стрим.

Теперь переведем сервис уведомления о штрафах из стандартного MVC в реактивный. Шкиперу должно понравиться.

Реактивное приложение

Начнем переводить наше приложение со стандартного MVC на WebFlux.

Чтобы перейти на WebFlux, нам нужно поменять зависимость с web на webflux. Мы получим готовый к использованию реактивный сервис.

Было Стало

Изменим контроллер так, чтобы он возвращал реактивный тип:

И проведем нагрузочное тестирование(1000 единовременных пользователей):

Без нагрузки Под нагрузкой

Без нагрузки создался один поток reactor-http-nio-1. Он работает постоянно. Под нагрузкой NETTY масштабировал количество потоков до 12. Мой ноутбук 6-ядерный, работает в 12 потоках, поэтому NETTY масштабировал на количество потоков процессора. Они также все время работают и не простаивают.

1. Таблица MVC 2. таблица WebFlux

Нагрузочное тестирование показало: обработали быстрее, но получили большее количество ошибок. Непорядок.

«Что и требовалось доказать, еще не много и нас взорвут» — говорит Шкипер.

Нужно разобраться, в чем причина такого количества ошибок.

Основная проблема — блокирующие вызовы к БД и удаленному сервису. Netty делегирует обработку событий асинхронным потокам. Этих потоков критически мало по сравнению с Tomcat: 200 против 12

Если заблокируются все потоки в AsyncThreadPool, придется откидывать запросы, пока не освободится AsyncThreadPool.

Сперва сделаем БД реактивными. Для этого подключим реактивные драйверы на MongoDb и PostgreSql. Начнем с MongoDb.

Reactive Mongo Driver

MongoDb предоставляет свою реализацию reactive streams. Чтобы ее использовать, нам нужно поменять зависимости.

было стало

Теперь поменяем имплементацию репозитория и сменим ее на реактивную.

Было Стало

Теперь наш репозиторий реактивный. Вместо List возвращаем реактивный тип Flux. Он возвращает нам от 0 до N элементов. Реактивный драйвер MongoDb использует под капотом Netty, а в прошлых версиях asynchronous socket channel. Если хотите разобраться в этом глубже, переходите по ссылке.

Reactive Driver PostgreSql

Наступило время превратить нашу реляционная базу данных в реактивную.

Компания Pivotal релизнула spring-data-r2dbc (Декабрь 2019), что позволяет легко перейти на реактивный драйвер.

Было Стало

Изменения незначительные, репозиторий имплементирует r2dbc репозиторий и возвращает Flux.

Было Стало

Из интересных фактов: под капотом свою работу выполняет Netty. Для разбора закрепляю ссылку на r2dbc-driver.

WebClient

Перейдем к самому интересному — интеграции с удаленном сервисом. Вместо RestTemplate будем использовать более удобный и крутой WebClient.

Было Стало

Client возвращает реактивный тип Mono.

Reactive Service

Теперь приступим к изменению сервиса и контроллера, так как они должны возвращать тоже реактивные типы.

Было Стало

Reactive Controller

Также меняем контроллер.

Было Стало

MediaType.APPLICATION_STREAM_JSON_VALUE дает понять контроллеру, что мы будем стримить данные пользователю пачками. То есть, как будет готов объект NotificationDTO, он сразу отгрузится пользователю, не дожидаясь остальных.

Как это выглядит в браузере:

Данные приходят не массивом, а пачками, по готовности transfer-encoding: chunked → позволяет надежно доставлять данные от сервера без необходимости заранее знать точный размер всего HTTP-сообщения. Как доказательство не присутствует Content-Length.

Теперь с пользователем общаемся с помощью событий. Каждое уведомление(NotificationDTO) и есть событие, которое нужно обработать. Пользователь не нужно ждать всего ответа.

Осталось поменять application.yaml.

Было. Обратите внимание на Jdbc(блокирующий драйвер). Стало. Поменял jdbc → на r2dbc. Для MongoDB настройки остались такими же

Нагрузочное тестирование реактивного приложения

Из нагрузочного тестирования видно, что мы смогли обработать 1000 одновременных запросов за 2:35, что быстрее MVC на 3 сек. Количество ошибок меньше на 9%. Реактивный сервис обработал большее количество запросов при меньшем количестве потоков. Заглянем в профилировщик.

Без нагрузки. Общее количество потоков составило 30(Netty). У MVC 34(Tomcat) Под нагрузкой. Общее количество потоков составило 77(Netty). У MVC 221(Tomcat). Потоки работают на максимуме, используя всю мощность процессора.

Не напрягая зрение видно, что, помимо потоков приложения(reactor-htp-nio), появились еще два вида потоков:

reactor-tcp-nio — потоки для обслуживания r2dbc драйвера

nioEventLoopGroup — потоки реактивного драйвера MongoDB

Модернизированный сервис уведомления о штрафах

Новая архитектура позволяет делать выводы, что сервис отвечает требованиям Reactive Manifesto:

Responsive(отзывчивость) — с пользователем общаемся с помощью событий. Он получает все частями и работает с ними, даже если в процессе возникнет ошибка, пользователь получит часть данных.

Elastic(Эластичность) — приложение использует минимальное количество потоков, они не простаивают и работают на максимум. Также применимо вертикальное масштабирование. Мощнее процессор, больше потоков.

Message Driven — сервисы должны общаться с помощью событий. Реактивный сервис с помощью реактивных драйверов и WebClient общаются между собой именно так. То же и с пользователем: за счет MediaType.APPLICATION_STREAM_JSON_VALUE стримим событиями.

Resilient(Устойчивость) — сервис должен адекватно реагировать на возникновение ошибок. В модернизированном приложении не делал никаких действий по устойчивости для чистоты эксперимента.

Ну что, скажешь на это, Шкипер?

Вопрос закрыт. Пингвины не справились с потоком штрафов, заказали судно и решили скрыться из страны. Миссия выполнена.

Вывод

WebFlux не про скорость обработки запроса, а про одновременное обслуживание большого количество запросов.

Нужно правильно продумать архитектуру приложения, чтобы не было блокирующих соединений. Система должна отвечать требованиям Reactive Manifesto.

Чтобы избавиться от блокировки бд и интеграции с медленными сервисами, используем реактивные драйверы и WebClient(R2dbc и Reactive MongoDb driver)

WebFlux лучше всего использовать для большого количества одновременных запросов(Высоконагруженные системы)

Если есть большое количество блокирующих соединений и малое количество одновременных запросов, лучше посмотреть в сторону стандартной реализаций MVC на tomcat

Источник

Информ портал о технике и не только