А насколько Loom реактивный?

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

Проект Loom добавит в Java 19 виртуальные треды. Что это? Новые перспективы для рынка труда нарисовались в предыдущей части заметки. В аспекте внутренностей JVM про Loom рассказывает Иван Углянский: рекомендую его доклад «Thread Wars — проект Loom наносит ответный удар».

Здесь мы оценим, как добавка повлияет на современные подходы серверной разработки. Потеснит ли новинка Scala и Kotlin с их фреймворками? Заодно ответим на вопрос «а в какой мере Loom — реактивный»?

Vert.x и Loom

C точки зрения Vert.x, новая добавка в Java — это не конкурирующий фреймворк, а движок. Сейчас Vert.x использует в качестве движка Netty. Что Vert.x выиграет, если перейдёт на Loom? Вменяемые стектрейсы. Они сильно упростят отладку и сопровождение реактивного приложения. Разработчики Vert.x прекрасно понимают это. В проекте уже имеется отдельная ветка для интеграции с Loom.

Spring и Loom

Дадим слово разработчикам Spring:

Первое, что приходит мне в голову — это spring-web*. Реализации [на базе] WebMvc — железобетонные и простые, тогда как реализации [на базе] WebFlux — масштабируемые и реактивные. Последнее идёт вместе с недостатками в виде усложнения кода, худшей читаемости и малой пригодности для отладки. Loom же обещает достигнуть масштабируемости путём порождения миллионов Фибров, и в то же время оставить код читаемым, сохраняя его организацию последовательной.

— эта исследовательская задача была включена в контрольную точку шестой версии Spring сразу после объявления о поставке Loom в JDK 19.

Реактивность и Loom

Манифест Йонаса Бонера (2014 год) определяет Реактивную систему как:

  • Отзывчивую: отвечает по возможности быстро.

  • Устойчивую: справляется со сбоями и делает это сама.

  • Эластичную: автоматически увеличивает и уменьшает потребление ресурсов в зависимости от нагрузки. Эластичность включает масштабирование.

  • Управляемую сообщениями: полагается на асинхронную обработку сообщений, что, помимо прочего, обеспечивает Обратное давление и формирует мониторируемые очереди сообщений. Коммуникация сообщениями неблокирующая.

Заметим, что в последний пункт является технологическим решением, из которого вытекают первые три. А заодно и пункт «стектрейс, до свиданья», который в манифест отчего-то добавить забыли.

В случае Loom техническим решением являются не обмен сообщениями, а легковесные потоки (или фибры, или горутины). Строго говоря, по Бонеру Loom — нереактивный. При этом он асинхронный и неблокирующим образом обрабатывает сообщения. С ним можно обеспечить отзывчивость и масштабируемость системы, как справедливо замечают разработчики Спринга. Из реактивного джентльменского набора проекту не хватает обратного давления и аналога мониторируемых очередей.

Обратное давление нужно, чтобы справляться с неравномерной нагрузкой. Сторонние библиотеки, вроде Vert.x, могут помочь с реализацией.

Очереди нужны, чтобы отслеживать изменяющуюся нагрузку. Пару лет назад техлид проекта Рон Преслер упомянул, что Даг Ли уже начал разработку каналов (неблокирующих очередей). Однако результатов пока не заметно ни в одном JEP.

Резюмируем, что в практическом смысле Loom обладает свойствами реактивной системы или решает её задачи.

Loom и реактивность нового поколения

В начале этого года Даниэль Спивак (принципал инженер Диснея) выдвинул тезис о том, что создал реактивный фреймворк следующего поколения. Даниэль справедливо замечает, что реактивность обычно связывают с управлением системными тредами — и правда очень дорогим и ограниченным ресурсом ОС. Однако существуют и другие разновидности резервов, количество которых лимитировано. Распоряжаться ими нужно очень бережно, иначе приложение перестанет работать устойчиво.

Специальная языковая конструкции try-with-resources появилась ещё в Java 7. Проблема в том, что этот механизм не работает в асинхронном режиме.

Scala-библиотека Cats Effect 3 авторства Спивака вводит дополнительные примитивы управления ресурсами.

И с ними можно писать, например, код гонок:

val uri1 = “jdbc:postgress:replica1”
val uri2 = “jdbc:postgress:replica2”

val joint: Resource[IO, Connection] =
connect(uri1).race(connect(uri2)).map(_.merge)

В этом случае происходит одновременное подсоединение к двум репликам БД. В результате дальнейший код будет использовать более быстрое соединение. Опоздавшее будет корректно финализировано и связанные с ним ресурсы освободятся.

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

Реактивность нового поколения предусматривает первоклассную поддержку:

  • гарантированного освобождения ресурсов;

  • отмены асинхронных операций с высвобождением ресурсов;

  • в частности, остановки по таймауту.

Если мы заглянем в Vert.x или Spring WebFlux, то не найдём там ничего подобного. Почему? Потому что ни библиотеки, на которых базируются эти фреймворки, ни сама Java не предоставляют примитивов, на чьей основе можно было бы построить нужные операции или методы.

Поможет ли в этом проект Loom? В рамках JEP 425 — нет. А вот сопутствующий JEP 428 описывает Структурную конкурентность (SC) как новую добавку в Java 19.

Подход SC реализован на самых разных платформах. Например, в библиотеке Котлиновских корутин. Вкратце, SC предоставляет альтернативный примитивам Cats Effect 3 способ управлять ресурсами при асинхронной организации кода. Там также возможны отмены и таймауты. Пока JEP 428 делает упор на управление исключительно тредами.

Мы видим, что разработчики Java нацелены придать языку способность строить системы уровня реактивных нового поколения. Пока эти намерения находятся на стадии инкубации. Открытым вопросом остаётся, получится ли у фреймворков высокого уровня (Vert.x, Spring и так далее) опереться на новые базовые примитивы. Как заметил создатель Java Джеймс Гослинг: «Непросто придумать семантику, которая бы работала как следует».

Заключение

В Java приходят изменения, которые позволят с одной стороны реализовать отзывчивые и масштабируемые системы, а с другой — облегчить сопровождение асинхронного кода. Процесс этот только начался. Сегодня для нового проекта на базе JDK лучше будет выбрать что-нибудь вроде Cats Effect 3 или Котлиновских корутин. Java намерена составить им конкуренцию, но когда-нибудь в отдалённом будущем и с пока неясным результатом.

В следующей части заметки мы мигрируем игрушечный проект на Loom. Посмотрим, каких усилий это потребует и что именно поменялось в результате.

Источник: https://habr.com/ru/post/669582/


Интересные статьи

Интересные статьи

Это NVIDIA GeForce RTX 3080 — видеокарта настолько редкая, что если вы ее сейчас и найдете, то за цену, за которую едва ли решите покупать. А это игровой ноутбук XMG NEO 17, в сост...
Некоторое время назад я научился конвертировать виртуальные машины в oracle cloud из ubuntu 20.04 в gentoo. Машины предоставляемые в рамках always free tier весьма маломощны. Это в частно...
В сложных ERP-системах многие сущности имеют иерархическую природу, когда однородные объекты выстраиваются в дерево отношений «предок — потомок» — это и организационная структура пред...
Довольно часто владельцы сайтов просят поставить на свои проекты индикаторы курсов валют и их динамику. Можно воспользоваться готовыми информерами, но они не всегда позволяют должным образом настроить...
Эта статья посвящена одному из способов сделать в 1с-Битрикс форму в всплывающем окне. Достоинства метода: - можно использовать любые формы 1с-Битрикс, которые выводятся компонентом. Например, добавле...