Я переосмысливаю поведение нашего приложения Spring MVC: лучше ли вытащить (поток Java8) данные из базы данных или позволить базе данных протолкнуть (реактивный / наблюдаемый) данные и используйте противодавление, чтобы контролировать количество.
Текущая ситуация:
User
запрашивает 30 самых последних статейService
выполняет запрос к базе данных и помещает 30 результатов вList
Jackson
перебираетList
и генерирует ответ JSON
Зачем менять реализацию?
Это довольно затратно по памяти, потому что мы все время храним эти 30 объектов в памяти. В этом нет необходимости, потому что приложение обрабатывает один объект за раз. Хотя приложение должно иметь возможность получить один объект, обработать его, выбросить и получить следующий.
Потоки Java8? (тянуть)
С java.util.Stream
это довольно просто: Service
создает Stream
, который использует курсор базы данных за кулисами. И каждый раз, когда Jackson
записывает строку JSON для одного элемента Stream
, он запрашивает следующий, который затем запускает курсор базы данных для возврата следующей записи.
RxJava / Reactive / Observable? (нажать)
Здесь у нас противоположный сценарий: база данных должна продвигать запись за записью, а Jackson
должен создавать строку JSON для каждого элемента, пока не будет вызван метод onComplete
.
то есть Controller
сообщает Service
: дайте мне Observable<Article>
. Затем Jackson
может запросить столько записей в базе данных, сколько сможет обработать.
Различия и проблемы:
С Streams
всегда есть некоторая задержка между запросом следующей записи в базе данных и ее получением / обработкой. Это может замедлить время ответа JSON, если сетевое соединение медленное или существует огромное количество запросов к базе данных, которые необходимо выполнить для выполнения ответа.
При использовании RxJava
данные должны быть всегда доступны для обработки. А если это слишком много, мы можем использовать противодавление, чтобы замедлить передачу данных из базы данных в наше приложение. В худшем случае буфер / очередь будут содержать все запрошенные записи базы данных. Тогда потребление памяти будет равно нашему текущему решению с использованием List
.
Почему я спрашиваю / о чем прошу?
Что я пропустил? Есть ли другие плюсы / минусы?
Почему (особенно) Spring Data Team расширила свой API для поддержки
Stream
ответов из базы данных, если всегда есть (короткая) задержка между каждым запросом / ответом базы данных? Это может привести к некоторой заметной задержке для большого количества запрошенных записей.Рекомендуется ли использовать
RxJava
(или другую реактивную реализацию) для этого сценария? Или я упустил какие-то недостатки?