Как стать автором
Обновить

Комментарии 14

Но к этим объектам можно обратиться отдельными запросами зная userId или personId. Быстродействие от этого не пострадает.

Смелое заявление.
Поля имеют примитивные типы.

И это проблема, о которой тактично умалчивают в книгах и статьях про reactor. Типа вот есть r2dbc, в нем все можно, дерзайте. Но при этом на нем банальный join сделать — то еще приключение, особенно если хочется с удобством JPA, а не JdbcTemplate. А ведь в реальных проектах отношений может быть огромное количество.
На счет преимуществ нативного SQL над JPQL в плане быстродействия. Думаю, если провести голосование, то большинство отдаст голос в пользу SQL. Поэтому не такой уж я и смелый в своем мнении.) На более низком уровне, SQL позволяет оптимизировать запросы в том числе и сложные с JOIN. Но интересно, конечно почитать специальные исследования об этом (о производительности). Пока нашел только quares.ru/?id=164860 где автор не поленился проверить эквивалентные запросы. У него JPA в полтора раза замедлил запрос. Конечно, это не исследование, но…
На счет преимуществ нативного SQL над JPQL в плане быстродействия. Думаю, если провести голосование, то большинство отдаст голос в пользу SQL. Поэтому не такой уж я и смелый в своем мнении.

Что-то все в кучу смешалось. Первое — про утверждение, что пачка запросов вместо одного не скажется на производительности. А именно отдельно подтягивать данные вместо join (по userId или personId). Так вот, скажется. Это почти всегда будет медленнее, чем прогнать один запрос. И тут не должно быть сравнения с JPA, тут речь не про это, на чистом SQL будет медленнее.
Второе — про JPA. Конечно же, с JPA запросы зачастую будут менее оптимальные, чем написанные грамотным DBA. Но! Во многих категориях приложений это не критично. Гораздо важнее скорость разработки, удобство использования и поддержки. Особо критичные места всегда можно подтюнить или на крайний случай написать нативный запрос руками. И вот этого удобного механизма в реактивщине еще нет. И как мне кажется, этого очень не хватает, чтобы reactor начали использовать по настоящему массово.
На счет пачки запросов, или отдельных запросов для каждого объекта — согласен, не самый лучший вариант в плане быстродействия. Подправил
Я правильно понимаю, что WebFlux — это аналог async / await и промисов из мира Node.js?
Можно и так считать если говорить о реактивности. В 1м случае реактивность поддерживается для бэкенда и во втором для фронтенда

async/await - это операторы асинхронности. Реактивность основывается на асинхронности, но асинхронный код - это не всегда реактивный код.

Следует учесть, что WebFlux для работы требуется встроенный в Spring сервер Netty. Встроенные Tomcat и Jetty не подходят.

Олег Докука в книге "Практика реактивного программирования в Spring 5" пишет, что можно использовать и Tomcat, который теперь поддерживает асинхронность благодаря спецификации Servlet 3.1, просто это будет менее эффективно.

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

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

Не путайте встроенные в Spring 5 серверы с серверами поддерживающими Servlet 3.1. Я же специально проиллюстрировал (1я картинка) на чем базируется реактивный стэк.

На счет потоков. На разных уровнях под потоком понимается разное. Понятие поток в реактивном программировании (реактивный поток) это поток данных. Например Flux.merge(a, b, c) объединяет три потока. Для Netty поток, это скорее цепочка (или цикл) событий привязанных к определенным задачам. Здесь можно найти детали programmer.help/blogs/netty-basic-to-entry-2-netty-core-functions-and-thread-model.html A thread and task queue are maintained in NioEventLoop, which supports asynchronous submission and execution of tasks
Для примера. Вот, как выглядит лог, когда одновременно запускаются реактивные потоки для 5 подписчиков (subscriber)
[INFO ] 2021-07-03T15:17:18.268Z [main] org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean | | — Creating Service {urn:cam-ws}CamWSService from class ws.cam.CamWS
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-3] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-4] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-5] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-2] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement
[DEBUG] 2021-07-03T15:17:20.031Z [reactor-tcp-nio-1] org.springframework.data.r2dbc.core.DefaultDatabaseClient | | — Executing SQL statement

Это не я, это создатель Spring WebFlux.

Со встроенными Tomcat и Jetty настроить реактивность сложнее и они, как минимум, должны поддерживать Servlet 3.1 (на момент написания статьи этого не было).

Спецификация Servlet 3.1 выпущена в 2013-м, а поддерживающие её Tomcat 8 и Jetty 9 выпущены в 2014-м.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории