1. Основы Reactive Streams и место Project Reactor
Основы Reactive Streams и место Project Reactor
Зачем нужен Reactive Streams
Реактивное программирование в Java появилось как практический ответ на две проблемы классического подхода блокирующих вызовов и потоков:
Reactive Streams решает это через стандартизированный протокол обмена данными с поддержкой backpressure (управления скоростью), чтобы потребитель мог явно сообщать, сколько элементов он готов принять.
Reactive Streams — это не «ещё одна библиотека», а спецификация (набор интерфейсов и правил взаимодействия).
Полезные источники:
Что такое Reactive Streams
Reactive Streams определяет минимальный набор ролей и сигналов для асинхронной потоковой обработки данных.
Основные роли:
Эти роли формируют контракт: как подписываться, как запрашивать элементы, как завершать поток и как обрабатывать ошибки.
Сигналы и жизненный цикл потока
Reactive Streams поток — это последовательность сигналов между Publisher и Subscriber.
Ключевые сигналы:
onSubscribe(subscription) — подписка установлена, Subscriber получил Subscription.request(n) — Subscriber просит у Publisher n элементов (это и есть backpressure).onNext(value) — Publisher отправляет очередной элемент.onError(error) — поток завершился с ошибкой (финальный сигнал).onComplete() — поток успешно завершился (финальный сигнал).cancel() — Subscriber отменяет подписку.Важное правило: после onError или onComplete никаких onNext быть не может.
!Диаграмма показывает порядок сигналов и как request(n) ограничивает выдачу элементов.
Backpressure простыми словами
Backpressure — это механизм, который не позволяет источнику «затопить» потребителя.
Интуитивная модель:
request(n) порциями.Если Subscriber запросил n, Publisher не имеет права отправить больше n элементов, пока не придёт следующий request.
Это принципиальное отличие от многих «push-only» подходов, где скорость диктует источник.
Где Reactive Streams находится в Java
Спецификация Reactive Streams не привязана к конкретной библиотеке. В Java есть стандартные интерфейсы в составе JDK:
java.util.concurrent.Flow.Publisherjava.util.concurrent.Flow.Subscriberjava.util.concurrent.Flow.Subscriptionjava.util.concurrent.Flow.ProcessorОни концептуально соответствуют Reactive Streams.
Документация JDK:
Однако сам по себе Flow — это только интерфейсы. Нужна библиотека, которая:
Здесь и появляется Project Reactor.
Место Project Reactor
Project Reactor — это реактивная библиотека для JVM, которая:
Официальные источники:
Flux и Mono: базовая модель
Reactor строится вокруг двух типов:
Mono<T> — асинхронный источник, который выдаёт либо 0 элементов (пусто), либо 1 элемент, либо ошибку.Flux<T> — асинхронный источник, который выдаёт 0..N элементов, либо ошибку.Примеры:
Важно понимать: subscribe(...) — это момент, когда вы подключаете подписчика и запускаете обработку. Многие реактивные цепочки по умолчанию ленивые: пока нет подписки, работа не выполняется.
Реактивная цепочка и операторы
Reactor поощряет стиль «конвейера»: вы собираете цепочку операторов, которые описывают что делать с данными.
Пример преобразований:
Типичные категории операторов:
map, flatMapfilter, takecollectList, reduceonErrorReturn, onErrorResumedelayElements, timeoutКак увидеть backpressure в Reactor
Reactor позволяет подписаться так, чтобы управлять запросами вручную (это полезно для обучения и диагностики).
Здесь Subscriber сначала просит 2 элемента, получает их через hookOnNext, затем снова просит следующую порцию.
Cold и hot источники: важная интуиция
В реактивных библиотеках часто различают:
Flux.range, повторный HTTP-запрос при каждой подписке).На старте курса достаточно запомнить: тип источника влияет на то, что увидят разные подписчики и когда реально начинается работа.
Потоки выполнения и Scheduler: что Reactor делает с потоками
Reactive Streams сам по себе не гарантирует «магическую многопоточность». Реактивность — про асинхронность, неблокирующий подход и управление давлением, а не про параллелизм.
В Reactor за переключение потоков обычно отвечают:
publishOn(scheduler) — меняет поток, в котором дальше обрабатываются сигналы.subscribeOn(scheduler) — влияет на то, где выполняется подписка и генерация источника.Вы подробно разберёте это в следующих темах курса, но важно помнить уже сейчас:
Ошибки и завершение: базовые правила
Reactive Streams поток завершается ровно один раз, одним из способов:
onCompleteonErrorcancelReactor даёт декларативные способы обработки ошибок:
Эта модель важна для проектирования API: ошибка — это такой же «сигнал», как данные, а не исключение, которое обязательно должно пробрасываться вверх по стеку.
Совместимость экосистемы
Поскольку Reactor реализует Reactive Streams, он хорошо сочетается с другими компонентами JVM-мира, которые тоже опираются на этот стандарт.
На практике это означает:
Publisher-типами без жёсткой привязки к конкретной реализации,Итоги
Теперь у вас есть опорные понятия, на которых держится весь курс:
Publisher/Subscriber/Subscription и протокол сигналов.Mono/Flux и множество операторов.В следующих материалах курса вы углубите понимание Mono/Flux, операторов, управления потоками (Schedulers) и типовых паттернов построения реактивных пайплайнов в реальных приложениях.