Реактивное программирование: понятие, обучение, особенности и советы специалистов

Принципы реактивного программирования не новы, и их можно проследить с 70-х и 80-х годов в основополагающих работах Джима Грея и Пэта Хелланда по тандемной системе.

Джеймс Николас «Джим» Грей

Эти люди намного опередили свое время. Только в последние 5-10 лет технологическая индустрия была вынуждена пересмотреть существующие «лучшие практики» для развития корпоративной системы. Она научилась применять знания о реактивных принципах сегодняшнего мира многоядерных и облачных вычислений.

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

Основы реактивного программирования

Это программирование направлено на потоки информации и распространение изменений данных. При использовании языков программирования легко выделить статические и динамические потоки, при этом базовая модель автоматически распространит изменения через все потоки данных. Говоря простыми словами, в потоках данных программирования Rx, испускаемых одним компонентом, и базовая структура, предоставляемая библиотеками Rx, будет распространять эти изменения на другой компонент, зарегистрированный для получения этих изменений. Реактивное программирование Rx состоит из трех ключевых моментов.

rx состоит из трех ключевых моментов

Основные функции компонентов:

  1. Наблюдаемые - не что иное, как потоки данных. Наблюдаемый упаковывает данные, которые могут передаваться из одного потока в другой. Они в основном испускают данные периодически или только один раз в своем жизненном цикле на основе конфигураций. Существуют различные операторы, которые могут помочь наблюдателю отправить некоторые конкретные данные на основе определенных событий.
  2. Наблюдатели потребляют поток данных, излучаемый наблюдаемым. Наблюдатели подписываются с помощью метода реактивного программирования subscribeOn () для получения данных, передающих наблюдаемым. Всякий раз, когда наблюдаемый передаст данные, все зарегистрированные наблюдатели получают данные в обратном вызове onNext (). Здесь они могут выполнять различные операции, такие как разбор ответа JSON или обновление пользовательского интерфейса. Если есть ошибка, вызванная наблюдаемым, наблюдатель получит ее в onError ().
  3. Планировщики (расписание) - это компонент в Rx, который сообщает наблюдаемым и наблюдателям, по какому потоку они должны работать. Можно использовать метод observOn (), чтобы сообщать наблюдателям, на каком потоке они должны наблюдать. Кроме того, можно использовать schedOn (), чтобы сообщить наблюдаемому, в каком потоке они должны запускаться.

В реактивном программировании с использованием RxJava предусмотрены основные потоки по умолчанию, такие как Schedulers.newThread () создадут новый фон. Schedulers.io () выполнит код в потоке ввода-вывода.

Преимущества и ограничения метода

Преимущества и ограничения метода

Основными преимуществами Rx являются увеличение использования вычислительных ресурсов на многоядерном и многопроцессорном оборудовании, повышение производительности за счет сокращения точек и повышение производительности за счет сокращения точек сериализации, согласно Закону Амдаля и Универсального закона о масштабируемости Гюнтера.

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

Там, где возникает Rx, создается процесс создания компонентов и состав рабочих процессов. Чтобы полностью использовать асинхронное выполнение, включение противодавления имеет решающее значение, чтобы избежать чрезмерного использования или, скорее, неограниченного потребления ресурсов. Чтобы обеспечить устойчивое состояние с точки зрения потока данных, обратное давление на основе нагрузки отсылает спрос, протекающий вверх по потоку, и принимает сообщения.

Таким образом, основными преимуществами системы являются:

  1. Повышенная производительность - благодаря возможности быстро и стабильно обрабатывать огромные объемы данных.
  2. Улучшенный UX - из-за того, что приложение больше реагирует на пользователя.
  3. Упрощенные модификации и обновления - благодаря более читабельному и более легкому прогнозированию кода.

Но несмотря на то, что Reactive Programming - очень полезная штука при создании современного программного обеспечения, чтобы рассуждать о системе на более высоком уровне, нужно использовать другой инструмент - Reactive Architecture для процесса проектирования реактивных систем. Кроме того, важно помнить, что существует много парадигм программирования, и Rx - это лишь один из них, как и любой инструмент, он не предназначен для всех случаев использования.

Устойчивость реактивных систем

Устойчивость - это отзывчивость при неудаче и является неотъемлемым функциональным свойством системы. Для нее нужны разработки, а не просто добавление в систему в ретроактивном виде. Устойчивость реактивного программирования javascript выходит за пределы отказоустойчивости и это происходит не из-за деградации, а в случае неудачи она может полностью сама исправиться.

Для этого требуется изоляция компонентов и сдерживание отказов, чтобы избежать сбоев, распространяющихся на соседние компоненты, что может привести к катастрофическим сценариям с каскадными сбоями. Таким образом, ключом к созданию систем Resilient — самовосстановления — является то, что они могут быть охарактеризованными как сообщения, отправленные на другие компоненты, которые действуют как супервизоры и управляются из безопасного контекста вне отказавшего компонента.

Здесь, будучи управляемыми сообщениями, эти средства отходят от сильно связанных, хрупких, глубоко вложенных синхронных цепочек вызовов, которые в большинстве случаев игнорируются. Идея состоит в том, чтобы отделить управление отказами от цепочки вызовов, например, освобождая клиента от ответственности за обработку сбоев сервера.

Производительность системной архитектуры

Производительность системной архитектуры

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

Реактивные системы представляют собой наиболее производительную системную архитектуру, в контексте многоядерных, облачных и мобильных архитектур:

  1. Изоляция отказов предлагает переборки между компонентами, предотвращая отказы от каскадирования и ограничивая объем и степень отказов.
  2. Иерархии супервайзеров предлагают несколько уровней защиты в сочетании с возможностями самовосстановления, что устраняет множество временных отказов от каких-либо эксплуатационных затрат для расследования.
  3. Пропуск передачи сообщений и прозрачность местоположения позволяют отключать и заменять компоненты, не затрагивая работу конечного пользователя. Это снижает стоимость сбоев, их относительную актуальность, а также ресурсы, необходимые для диагностики и исправления.
  4. Репликация снижает риск потери данных и уменьшает влияние сбоя на доступность поиска и хранения информации.
  5. Эластичность позволяет сохранять ресурсы по мере того, как использование колеблется, что минимизирует эксплуатационные расходы при низкой загрузке и риск сбоев или срочных инвестиций в масштабируемость по мере увеличения нагрузки.

Отношение к традиционным веб-приложениям

Отношение к традиционным веб-приложениям

Веб-приложения могут в значительной степени выиграть от стиля разработки с Rx, что позволяет составить рабочие процессы запроса-ответа, включающие разветвление на вызовы служб, асинхронное извлечение ресурсов и составление ответов, и последующую сортировку для клиента. Совсем недавно push-а-серверные события и веб-сокеты стали все чаще использоваться на практике, и для выполнения этого в масштабе требуется эффективный способ хранения множества открытых подключений и где IO не блокирует.

Для этого есть инструменты,например, Streams and Futures, которые делают простыми неблокирующие и асинхронные преобразования, и подталкивает их к клиентам. Реактивное программирование c уровнем доступа к данным - обновляет и запрашивает их в эффективном ресурсе, предпочтительно с использованием баз данных SQL или NoSQL с асинхронными драйверами.

Веб-приложения также выигрывают от разработки реактивной системы для таких вещей, как распределенное кэширование, согласованность данных и уведомления с несколькими узлами. Традиционные веб-приложения обычно используют стоящие узлы. Но как только программисты начинают использовать Server-Sent-Events (SSE) и WebSockets — эти узлы становятся работоспособными, поскольку, как минимум, они поддерживают состояние клиентского соединения, а push-уведомления направляются к ним соответствующим образом. Для этого требуется разработка реактивной системы, так как это область, где важна адресация получателей посредством обмена сообщениями.

Суть реактивное программирование Java

Не требуется обязательно использовать Rx в реактивных системах. Потому что Rx программирование и реактивные системы — не одно и тоже. Хотя они часто используются взаимозаменяемые термины, но не являются точными синонимами и отражают разные вещи. Системы представляют собой следующий уровень «реактивности». Этот уровень подразумевает конкретные проектные и архитектурные решения, которые позволяют создавать устойчивые и гибкие приложения.

Тем не менее очень хорошая идея — комбинация методов — приносит еще больше преимуществ приложениям, так как делает их еще более связанными, позволяет более эффективно использовать ресурсы и обеспечивает более низкую задержку. Когда речь идет об огромных объемах данных или многозадачности, часто нужна асинхронная обработка, чтобы системы были быстрыми и отзывчивыми.

В Java - представителе старого объектно-ориентированного программирования, асинхронность может стать действительно сложной и сделать код трудно понятным и поддерживаемым. Таким образом Rx особенно полезно для этой «чисто» объектно-ориентированной среды, поскольку оно упрощает работу с асинхронными потоками.

С его последними выпусками, начиная с Java 8, сама Java сделала некоторые попытки внедрить встроенную реактивность, но эти попытки сегодня не очень популярны у разработчиков. Тем не менее есть некоторые живые и регулярно обновляемые сторонние реализации для реактивного программирования Java, которые помогают сэкономить день и поэтому особенно ценятся разработчиками Java.

Kotlin: начальный тест производительности

Kotlin: начальный тест производительности

В обычном приложении для Android программисты обычно неоднократно выполняют некоторые операции реактивного программирования с использованием RxJava, поэтому нужно сравнить скорость, использование процессора и памяти с теми же операциями, которые были реализованы как с сопрограммами Kotlin, так и с RxJava. Это начальный тест производительности.

Всякий раз, когда применяется новый инструмент, который будет широко использоваться во всем кодексе, важно понять, повлияет ли оно на общую производительность приложения, прежде чем принимать решение о том, насколько целесообразно использовать его. Практика использования дает короткий ответ: в большинстве случаев пользователям стоит подумать о замене RxJava на сопрограммы Kotlin, особенно в Android.

Реактивное программирование с применением RxJava может по-прежнему использоваться в ограниченном количестве случаев, и в этих случаях можно смешивать, как RxJava, так и сопрограммы.

Простые причины:

  1. Обеспечивают гораздо большую гибкость, чем обыкновенное Rx.
  2. Предоставляет богатый набор операторов в коллекциях, которые будут выглядеть так же, как с операторами RxJava.
  3. Реактивное программирование Kotlin могут взаимодействовать при необходимости с использованием rxjava.
  4. Они очень легкие и эффективные, учитывая более высокий уровень использования ЦП для сбора мусора со всех объектов, созданных RxJava.

Реактивные расширения

Reactive Extensions (ReactiveX или RX) - это библиотека, которая следует за принципами Rx, то есть составление асинхронных и основанных на событиях программ с использованием наблюдаемой последовательности. Эти библиотеки предоставляют множество интерфейсов и методов, которые помогают разработчикам писать чистый и простой код.

Реактивные расширения доступны на нескольких языках. Программисты особенно заинтересованы в RxJava и RxAndroid, так как андроид - это самая сфокусированная область.

Реактивное программирование с использованием RxJava - это реализация Java Reactive Extension из Netflix. В основном это библиотека, которая составляет асинхронные события, следуя шаблону наблюдателя.

Можно создавать асинхронный трафик, преобразовывать и потреблять их наблюдателем в разных потоках данных. Библиотека предлагает широкий спектр удивительных операторов, таких как карта, объединение и фильтр, которые могут быть применены к потоку данных. Когда программист начнет использовать фактические примеры кода, он узнает больше об операторах и преобразованиях.

Многопоточность в приложениях Android

Android" class="if uuid-2938324" src="/misc/i/gallery/73564/2938324.jpg" />

Android реактивное программирование (RxAndroid) специфичен для платформы Android с несколькими добавленными классами поверх RxJava. Более конкретно — планировщики представлены в RxAndroid (AndroidSchedulers.mainThread ()), который играет важную роль в поддержке концепции многопоточности в приложениях для Android.

Помимо всего прочего, специалисты советуют использовать только библиотеку RxJava. Даже благодаря большому количеству планировщиков, используемых в программировании для Android.

Ниже приведен список планировщиков и их краткое содержание:

  1. Schedulers.io () - используется для выполнения неинтенсивных операций, таких как сетевые вызовы, чтение дисков /файлов, операций с базами данных и который поддерживает пул потоков.
  2. AndroidSchedulers.mainThread () - обеспечивает доступ к основной теме Thread / UI. Обычно в этом потоке происходят операции, такие как обновление пользовательского интерфейса, взаимодействие с пользователем. Специалисты советуют пользователям, что они не должны выполнять какие-либо интенсивные операции над этим потоком, так как это может вызвать бросок приложения или диалог ANR.
  3. Schedulers.newThread () - используя это, новый поток будет создан каждый раз, когда запланирована задача. Обычно предлагается не использовать расписание для очень продолжительных работ. Нити, созданные с помощью newThread (), не будут повторно применяться.
  4. Schedulers.computation () - этот график может применяться для выполнения интенсивных операций с процессором, по обработке огромных данных центра реактивного программирования, обработка растровых изображений. Количество потоков, созданных с использованием этого планировщика, полностью зависит от количества доступных ядер ЦП.
  5. Schedulers.single () - этот планировщик выполнит все задачи в следующем порядке, что можно использовать, когда требуется необходимость последовательного выполнения.
  6. Schedulers.immediate () - этот планировщик выполняет задачу немедленно, синхронно блокируя основной поток.
  7. Schedulers.trampoline () - выполняет задачи в режиме First In-First Out. Все запланированные задачи будут выполняться одна за другой, ограничивая количество потоков фона одним.
  8. Schedulers.from () - позволяет создавать планировщик от исполнителя, ограничивая количество создаваемых потоков. Когда пул потоков занят, задачи будут поставлены в очередь.

Основные примеры RxJava

Теперь, когда есть хорошие теоретические знания об RxJava и RxAndroid, можно перейти к некоторым примерам кода, чтобы лучше понять концепцию. Для начала работы нужно добавить зависимости RxJava и RxAndroid к проектам build.gradle и синхронизировать проект.

Основные этапы.

Основные этапы

Программирование.

Основные примеры RxJava

Observer подписывают на Observable, чтобы он мог начать получать данные, используя два метода:

  1. SubscribeOn (Schedulers.io ()) - говорит Observable, чтобы запустить задачу в фоновом потоке.
  2. ObservOn (AndroidSchedulers.mainThread ()) - указывает Observer получать данные в потоке пользовательского интерфейса Android.
Данные в потоке Android

Вот и все, таким образом программист сможет написать свою первую программу реактивного программирования с RxJava.

Предприятия и поставщики промежуточного программного обеспечения начали использовать Reactive, а в 2016 -2018 годах наблюдался огромный рост корпоративной заинтересованности в принятии этой парадигмы.

Rx предлагает производительность для разработчиков благодаря ресурсоэффективности на уровне компонентов для внутренней логики и преобразования потока данных, в то время, как реактивные системы предлагают производительность для архитекторов и DevOps, благодаря устойчивости и эластичности на уровне системы. Они применяются для создания «Cloud Native» и других широкомасштабных распределенных систем. На практике также широко используют книги о реактивном программировании Java с методами позволяющих комбинировать принципов проектирования реактивных систем.

Статья закончилась. Вопросы остались?
Комментарии 0
Подписаться
Я хочу получать
Правила публикации
Редактирование комментария возможно в течении пяти минут после его создания, либо до момента появления ответа на данный комментарий.