Основы реактивного программирования на Java. WebFlux + R2DBC


Основы реактивного программирования на Java. WebFlux + R2DBC

Вступление

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

Рассмотрим, пожалуй, самую популярную область IT - веб-разработку. Для стека на Java/Kotlin там часто применяются различные компоненты Spring Framework (Spring Data JPA, Spring MVC, драйвера баз данных). 

Но с  появлением пятой версии туда был встроен модуль под названием WebFlux. Этот микрофреймворк является альтернативой Spring MVC и отражает собой реактивный подход для написания веб-сервисов. 

В основе WebFlux лежит уже известная нам библиотека Project Reactor, позволяющая легко запрограммировать неблокирующие потоки, работающие с вводом/выводом данных.


Spring MVC vs WebFlux

Основные отличия двух модулей лучше всего демонстрирует официальная документация. 

Главным отличием является использование WebFlux-ом встроенного в Spring сервера Netty. Встроенные Tomcat и Jetty не подходят.

Также стоит отметить, что WebFlux поддерживает как обычные REST-контроллеры, применяемые в Spring MVC, так и RouterFunctions, использующие функциональный подход в написании кода.


А что по производительности?

Несмотря на отличие данных в различных источниках, а также результатах собственного исследования, на их основе можно однозначно сказать - WebFlux выигрывает у Spring MVC в количестве одновременно обрабатываемых запросов, начиная с нагрузки примерно в 300 пользователей. При предельной же загруженности сервера в реактивном режиме может одновременно обслуживаться в 2 раза больше пользователей.



R2DBC

Одной из самых долгих операций в веб-сервисах является, безусловно, запрос в базу данных. Здесь Spring тоже поддерживает реактивных подход в лице модуля Spring Data R2DBC (Reactive Relational Database Connectivity). В данный момент он находится на этапе развития, но основные поставщики реляционных баз данных (Oracle, PostgreSQL, MySQL) уже обеспечили его реактивными драйверами. 

Главным недостатком R2DBC является отсутствие аналога Hibernate, что не позволяет с помощью Java описывать сложные связи между объектами или программно задать ограничение целостности таблиц. 

Также существует много споров о том, является ли вообще R2DBC производительнее старого доброго JDBC. Чтобы их решить, нужно было написать собственный бенчмарк, в результате работы которого были получены такие результаты (использовался Apache JMeter, 200 одновременных пользователей, каждый по 500 запросов):


Пропускная способность оказалась примерно одинаковой для всех запросов, кроме получения первых 100 записей. Это обусловлено временем парсинга ответа БД с помощью R2DBC. 

JDBC thread dump
R2DBC thread dump
Но что касается оптимизации потоков и количества используемой памяти - тут R2DBC вне конкуренции. Это означает, что при росте нагрузки на сервис, R2DBC всё-таки будет справляться лучше, чем JDBC.

Заключение
Несмотря на все преимущества связки WebFlux + R2BDC, не стоит бежать и переписывать все свои проекты на реактивщину. Spring MVC + JDBC прекрасно справляется, если сервис не сталкивается с небывалыми раннее нагрузками или пользователям не важна каждая миллисекунда в ожидании ответа.