Как заставить системы общаться

опубликовано: ⏰ 9

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

Общее описание по EIP (Enterprise Integration Patterns) можно найти на сайте enterpriseintegrationpatterns.com.

Введение

Интеграция – это процесс объединения различных систем и сервисов для обеспечения эффективного обмена данными и взаимодействия между ними.

Если отбросить технические детали реализации, то можно выделить несколько подходов организации обмена между системами:

  1. Удалённый вызов процедур (RPI/RPC) – взаимодействие, где одна система вызывает метод другой системы через некий API с известным контрактом.
  2. Сообщения – взаимодействие через обмен небольшими сообщениями между двумя системами, используя, например, брокеры сообщений или их аналоги.
  3. Передача файлов – обмен данными через файлы, расположенные на общем сетевом ресурсе или через распределённые файловые системы.
  4. Общая база данных – обмен данными, хранящимися в общей базе данных, доступной для нескольких систем.

Удалённый вызов процедур (RPI)

В большинстве случаев, это синхронное взаимодействие по своей сути – запрос и ответ. Хотя после выполнения запроса (установки соединения), одна или обе стороны могут продолжить работу в асинхронном режиме. Как пример – gRPC Streaming, WebFlux.

Используются в случаях:

  • Требуется получение ответа на запрос немедленно или в короткий срок.
  • Когда очереди слишком дорого и сложно или необходимо пересматривать архитектуру существующих приложений.
  • Практически любое клиент-серверное взаимодействие для десктоп/веб-приложений. Хотя можно и к очередям из браузера в случае с NATS, через WebSockets.
  • “У нас старая система – переделывать не будем”.

Примеры протоколов:

В чём плюсы такого подхода:

  • Простота, так как это наверное самый привычный и понятный подход для вызова функции во внешней системе (P2P), по аналогии с вызовом процедур в коде.
  • Получаем ответ сразу после запроса, без необходимости использования статусов/состояний для запросов и ожидания ответа.
  • Использование предопределённых контрактов для API, которые описываются в формате используемого протокола, например:

В чём минусы такого подхода:

  • Возможные проблемы с задержками (latency) на больших объёмах данных или высокой частоте запросов. Упираемся в аппаратные ограничения сети, процессора, памяти и т. д.
  • Относительно низкая доступность систем. Отказ системы ведёт к отказу в обработке вызовов, что в свою очередь должно корректно обрабатываться на стороне клиента. Естественно, для повышения доступности строятся кластеры и настраиваются балансировщики нагрузки, но не всегда и не везде, к сожалению.
  • Синхронные вызовы блокируют ресурсы на стороне клиента и на стороне сервера до завершения вызова.

Сообщения

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

В основном применяется, там где не требуется ответ сразу:

  • Быстрого ответа не требуется и можно организовать межсервисное взаимодействие асинхронно.
  • Операции выполняются довольно продолжительное время и не хочется блокировать ресурсы.
  • Для потоковой обработки больших объёмов данных (ETL/Data Streaming).

Примеры брокеров сообщений:

В чём плюсы такого подхода:

  • Отсутствие блокировок на стороне клиента и сервера, низкие задержки.
  • Поддержка гарантированной доставки сообщений с подтверждением получения.
  • В общем случае, возможность простого масштабирования производительности обработки сообщений за счёт добавления новых потребителей или продюсеров сообщений.
  • Высокая доступность системы за счёт репликации очередей, развёртывания в кластере.
  • Так же как и с RPI есть возможность описывать формат сообщений, а также контракт взаимодействия. Примеры:

В чём минусы такого подхода:

  • Повышается сложность системы из-за использования подхода с асинхронным взаимодействием. В случае EDA необходимо более тщательно продумывать, как её компоненты будут обмениваться данными и менять своё состояние.
  • Не всегда так просто взять и настроить брокер сообщений, каждый со своими проблемами и особенностями:
    • Зависимость от аппаратной составляющей – падающие и выходящие из строя сервера, низкая производительность сети и т. д.
    • Зависимость от программной составляющей – отдельная головная боль, это различные баги и проблемы в самих брокерах, клиентских библиотеках, отсутствие необходимой функциональности (например, надёжной репликации между узлами брокера).
  • Относительно высокая сложность в настройке и поддержке всех компонентов системы.

Передача файлов

Некий вариант асинхронного взаимодействия. Кладём один файл в каталог, а другая система когда-нибудь его заберёт и возможно положит файл с ответом.

Может быть использовано для:

  • Обмена файлами между старыми системами, когда нет возможности доработать и добавить новое API.
  • Передачи больших файлов, когда их передача через другие каналы может нести большие накладные расходы. Например, в случае использования брокеров сообщений, файлы обычно выгружаются на диск, а затем ссылка на них передаются в сообщении.

Примеры:

В чём плюсы такого подхода:

  • Простой в реализации и понимании способ обмена. Кладём файл (с индикацией блокировки на время операции), другая система забирает и обрабатывает.
  • Относительная хорошая надёжность хранения данных, если хранилище построено с учётом отказоустойчивости и права доступа к ней ограничены.

В чём минусы такого подхода:

  • Разнородность форматов файлов, так как выгрузить могут всё что угодно. Необходимо проверять целостность и полноту данных обработкой.
  • Довольно легко потерять данные, вариации на тему rm -rf /.
  • Возможно сейчас с SSD/NVME дисками и не минус вовсе, но при больших объёмах передаваемых данных диски могут стать узким местом по IOPS.
  • Низкая отказоустойчивость в большинстве случаев. На практике, не так часто готовы вкладывать ресурсы человеческие и финансовые в развёртывание распределённых файловых систем, используют обычные сетевые (NFS/SMB) со всеми их сопутствующими проблемами.

Общая база данных

Синхронное взаимодействие или асинхронное – смотря с какой стороны посмотреть. Если выполнение операции DML/DDL, то наверное синхронное. Если с точки зрения обмена данными через таблицы, то похоже на асинхронное. Да и некоторые СУБД поддерживают подписки на события в СУБД (PostgreSQL LISTEN)

Может быть использовано для:

  • Как и в случае с передачей файлов - обмен данными между старыми системами, когда нет возможности доработать и добавить новое API.
  • Обработка событий, которые нельзя добавить в существующую систему (например, устаревшая замещаемая система, больше не поддерживается и не разрабатывается). Отдельный сервис отслеживает изменения в таблицах и выполняет определённые действия, такие как отправка уведомлений или обновление данных в другой системе.
  • Общие данные в двух и более системах. Да, это плохая практика и нарушает изоляцию, но такое тоже возможно.

В чём плюсы такого подхода:

  • Отсутствие необходимости дорабатывать существующие системы, когда необходимо получить прямой доступ к их оперативным данным.
  • Не требуется доработок API, усложнения инфраструктуры (ФС, брокеры и прочее).

В чём минусы такого подхода:

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

Сервисная шина предприятия (ESB)

Отдельно стоит упомянуть сервисные шины предприятия (ESB).

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

ESB зачастую могут объединять в себе несколько подходов к интеграции. Они часто используются для обеспечения централизованного управления процессами взаимодействия между различными системами. То есть в гетерогенных средах (SOA, MSA), где один сервис написан на C# (SOAP), другой - на Java (REST) и третий - на Node.js (GraphQL). ESB может взять на себя роль посредника и обеспечить единообразный интерфейс взаимодействия между ними, скрыв особенности реализации API каждого из сервисов.

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

ETL

Нельзя не упомянуть и инструменты для организации ETL конвейеров. Но вкратце, так как тема довольно обширная.

Наверное, самый известный и популярный из них (для меня по крайней мере :) это Apache Camel. Довольно мощный инструмент, который позволяет создавать маршруты для обработки и трансформации данных между различными источниками и поддерживает все основные EIP.

Второй из них, можно сказать Apache Camel с GUI – Apache NiFi. Он позволяет создавать графические конвейеры для обработки данных и имеет множество возможностей для мониторинга и управления этими конвейерами.

Сюда же можно добавить:

  • Apache Flink – распределенная система обработки потоковых данных с высокой производительностью.
  • Apache Airflow – платформа для управления рабочими процессами, которая позволяет автоматизировать процессы обработки данных.

Наблюдаемость систем

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

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

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

Напоследок побуду Капитаном Очевидность. Есть один момент, который стоит упомянуть – наблюдатель не должен быть наблюдаемым, как бы странно это не звучало. Это значит, что не нужно делать мониторинг в той же системе, которую необходимо мониторить. Роняем такую систему и теряем её же мониторинг.

Список далеко не полный, но наверное, самые распространённые и известные инструменты из них:

Заключение

Кратко в этот раз. Нет универсального подхода или инструмента, всё зависит от проекта, требований, сроков и ограничений Заказчика. Выбор инструментов должен учитывать всё вводные именно вашего проекта, а не чьи-то абстрактные рекомендации :)

Integrations Esb Etl Essentials