.. _architecture: Архитектура =================== .. contents:: :depth: 2 Платформа Citeck построена на микросервисной событийно-ориентированной архитектуре, что обеспечивает горизонтальное масштабирование, независимое развёртывание компонентов и гибкость при интеграции с внешними системами. Каждый микросервис отвечает за свою предметную область: управление моделью данных, бизнес-процессами, уведомлениями, трансформацией контента и другими функциями. Основной способ взаимодействия между микросервисами — обмен сообщениями через брокер (RabbitMQ), а также REST API. Платформа поддерживает работу с различными источниками данных без необходимости копирования данных во внутренний репозиторий. Для работы с данными используется собственный язык запросов :ref:`Records API `. Перечень источников данных может быть легко расширен. Компоненты системы: - **DAO services** – сервисы работы с контентом и метаданными. В качестве источников данных могут использоваться Базы данных, 1С, SAP и другие; - **Process services** – сервисы управления бизнес-процессами, поддерживаются нотации моделирования бизнес-процессов BPMN; - **Application services** – сервисы управления приложениями Citeck, их версионностью и деплойментом; - **Data services** – сервисы работы с данными, в том числе валидации данных и их индексации; - **Integration services** – интеграционные сервисы, включая ЮЗДО; - **API gateway** – API шлюз, используется в том числе для запросов от пользовательского интерфейса (WEB и мобильного); - **Business logic services** – сервисы бизнес-логики и конфигурации. Интерфейс системы разработан на базе фреймворка **ReactJS** в виде статичных **JS библиотек**, которые раздаются через NGINX и работают под управлением веб-браузеров на пользовательских устройствах. Мобильный интерфейс разработан на базе фреймворка **React Native**, также поддерживается адаптивная верстка для мобильных браузеров. Запросы от пользовательских интерфейсов маршрутизируются через **NGINX** и **API шлюз**. ПО Citeck развертывается с использованием сервисов контейнеризации **Docker / Kubernetes**. .. image:: _static/arch/Arch_1.png :width: 700 :align: center Микросервисы -------------- .. image:: _static/arch/Arch_2.png :width: 700 :align: center | .. image:: _static/arch/Arch_2_1.png :width: 500 :align: center .. list-table:: :widths: 10 30 :header-rows: 1 :class: tight-table * - Компонент - Описание * - **ecos-proxy** - Контейнер с nginx (OpenResty) и UI статикой (JS + CSS). * - **ecos-gateway** - Микросервис реализует API шлюз взаимодействия от клиента к серверу. * - **ecos-apps** - Микросервис приложений Citeck, отвечающий за доставку приложений Citeck к целевым сервисам. * - **ecos-notifications** - Микросервис отправки уведомлений (email, push-нотификации и др.). * - **ecos-model** - Микросервис моделей. Отвечает за информацию о типах, шаблонах нумерации и о матрицах прав. * - **ecos-history** - Микросервис для хранения истории. Подписан на события в системе и сохраняет информацию о них в БД. * - **ecos-process** - Микросервис процессов. Отвечает за процессы BPMN. * - **ecos-eis** - Приложение Keycloak для аутентификации в системе. * - **opensearch** - Система индексации контента документов. * - **ecos-uiserv** - Микросервис UI конфигураций. Отвечает за формы, журналы, UI действия, темы, дашборды, локализацию, иконки, конфигурацию меню. * - **ecos-integrations** - Микросервис для интеграции с внешними системами (SAP, 1C, Rabbit MQ и тд.). * - **ecos-transformations** - Микросервис для преобразования (трансформации) контента. Например, генерация по шаблону, конвертация типа документов, накладывание штампов и др. * - **ecos-content** - Микросервис для обеспечения хранения файлов в системе в определенное файловое хранилище (S3). * - **zookeeper** - Распределенное key-value хранилище для координации приложений Citeck между собой. * - **Rabbit MQ** - Приложение для обмена сообщениями между микросервисами. Хранение данных ----------------- 1. Основная используемая реляционная база данных – **PostgreSQL**. 2. Хранение метаданных поддерживается в любой системе через адаптер (record source). Существующие адаптеры: **PostgreSQL, Oracle DB, MS SQL, Mongo DB, SAP HANA.** 3. Для хранения документов может быть использована БД **PostgreSQL, S3** -совместимое хранилище или внешняя ECM система через адаптер (например, разработан адаптер к системе OpenText). 4. Помимо баз данных используется также прямая запись в файловую систему для приложений **Zookeeper, Rabbit MQ и OpenSearch**. Зависимости компонентов ------------------------ .. image:: _static/arch/Arch_3.png :width: 700 :align: center 1. Центральной частью системы Citeck является абстракция ****, в качестве которой может выступать любой источник данных в любом из микросервисов Citeck. Для добавления новых источников достаточно реализовать определенный интерфейс и данные из этого источника могут быть свободно интегрированы со всей экосистемой Citeck (их можно отображать в журнале, редактировать и просматривать через формы, отправлять по ним уведомления, запускать по ним процессы и т. д.). Любой **** в общем случае может общаться со следующими сервисами: - **ecos-model** для автонумерации, делегирования полномочий и получения индивидуальных настроек прав; - **ecos-content** для работы с контентом; - **zookeeper** для работы с реестрами артефактов. Общение с источниками данных построено на базе универсального :ref:`Records API`. Зависимости от **** по микросервисам: - **ecos-uiserv** загружает атрибуты для фильтрации UI действий по заданным в конфигурации условиям; - **ecos-notifications** загружает атрибуты для заполнения шаблона уведомления; - **ecos-history** загружает атрибуты для сохранения записи в истории; - **ecos-process** загружает и меняет атрибуты в ходе выполнения BPMN процессов. 2. Почти все микросервисы работают с **Rabbit MQ** (события и команды) и с **Zookeeper** (события, конфигурация Citeck, реестры типов, аспектов, настроек прав, шаблонов нумерации, распределенные блокировки, внешние миксины) 3. **UI** (мобильный и браузерный) зависят от **ecos-gateway** (шлюз для доступа в систему) и от **ecos-uiserv** (микросервис с UI конфигурациями); 4. **ecos-gateway** зависит от **ecos-model** для получения информации по пользователям и группах, в которых они состоят. Эта информация используется для формирования JWT-токена с последующей отправкой его в остальные микросервисы для аутентификации и авторизации; 5. **ecos-integrations** зависит от внешних систем, с которыми настроена интеграция. 6. **ecos-content** зависит от места хранения контента (S3). 7. **OpenSearch** зависит от источников данных для индексации контента и атрибутов. Взаимодействие клиента с сервером ----------------------------------- .. image:: _static/arch/Arch_4.png :width: 700 :align: center **1 этап.** При первом поступлении запроса от клиента **nginx** видит, что пользователь не имеет токена и отправляет его на **Keycloak** для аутентификации через протокол **OpenID Connect**. **2 этап.** **Keycloak** может предложить окно ввода логина/пароля или сразу выдать пользователю токен, с помощью которого он сможет зайти в систему (SSO). После успешной аутентификации пользователь перенаправляется на страницу, с которой его отправили в keycloak. **3 этап.** После того, как запрос прошел дальше, **ecos-gateway** смотрит на URL запроса и по нему решает, какой именно микросервис должен его обработать (например, запрос **/emodel/api/records/query** должен уйти в **ecos-model**). Для получения IP адреса и порта целевого микросервиса **ecos-gateway** обращается в **zookeper** за нужной информацией и, получив её, отправляет запрос дальше. Records API ------------- **Общее описание** :ref:`API`, разработанное для организации простого и легко масштабируемого общения между потребителем информации и источником данных. Язык запросов :ref:`Records API` объединяет в себе удобство обычных REST запросов в классическом REST API и оптимизированный и типизированный подход GraphQL, когда сервер отдает только те данные, которые нужны клиенту с предсказуемой типизацией. **Плюсы решения** 1. **Единый API** для доступа к данным в системе для всех потребителей (Браузер, Мобильное приложение, Система построения отчетов, Индексирование данных, Различные микросервисы, Интеграция и т.д.). 2. **Поддержка загрузки данных из связанных сущностей.** Например, если у нас договор ссылается на доверенность, то, имея идентификатор договора, мы можем получить любой атрибут связанной доверенности. 3. **Оптимальность.** Загружаются и вычисляются только те атрибуты, которые нужны потребителю. 4. **Простота в разработке** — разработчик источника данных (record source) описывает все атрибуты, которые могут запросить потребители вне зависимости от сложности их вычисления. Потребитель в запросе указывает только те атрибуты, в которых он заинтересован. 5. **Простота поддержки** — не требуется версионирование API, т.к. мы в любой момент можем добавлять новые атрибуты, не трогая старые. 6. **Тип получаемых данных полностью описывается запросом.** Из источника данных мы возвращаем атрибуты с любым типом, а Records API приводит их к нужному для потребителя. 7. **Вычисляемые атрибуты.** Возможность добавлять атрибуты, которые не хранятся в БД или любом другом хранилище, а вычисляются на основе существующих. 8. **Поддержка объединения атрибутов из разных источников.** Например, можно написать источник данных, который часть атрибутов будет брать из внешней БД, объединяя их по идентификатору. События ---------- .. image:: _static/arch/events_1.png :width: 700 :align: center :ref:`События` в Citeck позволяют менять атрибутивный состав, который нужен подписчику на событие, без модификации источника событий. При старте системы все подписчики регистрируют в Zookeeper список необходимых им событий по типам и атрибуты события, в которых они заинтересованы. Приложение, которое может отправлять события подобного типа, видит, что в системе есть подписчики на эти события, и, при их возникновении, подготовив необходимый список атрибутов, отправляет их в Rabbit MQ. Атрибуты описываются в формате :ref:`Records API` и могут пользоваться всеми преимуществами данного API. Система событий в Citeck гарантирует доставку как минимум одного сообщения вне зависимости от сбоев в системе. .. image:: _static/arch/events_2.png :width: 700 :align: center Команды -------- :ref:`Команда` — декларативное описание действия, которое нужно сделать на удаленном сервисе или локально. .. image:: _static/arch/command_1.png :width: 700 :align: center **Команды** в Citeck в качестве транспорта используют очереди RabbitMQ. Использование команд возможно как в синхронном, так и в асинхронном режиме. Целью команд могут быть: 1. Тип сервиса (ecos-process, ecos-uiserv и др.). Команду исполняет один из инстансов данного сервиса. 2. Инстанс сервиса (у каждого типа сервиса может быть много инстансов). 3. Все типы сервисов (широковещательные команды). Сервис-источник команды отправляет широковещательную команду в RabbitMQ и её обрабатывают все сервисы, которые в данный момент активны. Приложения ------------ :ref:`Приложения Citeck` позволяют выгружать из системы нужные артефакты в формате **zip** и деплоить их «на горячую» в другую систему. :ref:`Артефакт` – единица расширения в Citeck. Артефактами являются формы, журналы, типы, матрицы прав, действия, описания процессов и многие другие сущности в системе. Микросервис **ecos-apps** управляет артефактами, ведя их версионность и доставляя их до целевого микросервиса. Контент артефактов в системе неизменяемый и при любом изменении артефакта всегда создается новая версия, а старая сохраняется в списке версий. .. image:: _static/arch/Apps_1.png :width: 700 :align: center **Доставка артефактов** при старте системы происходит в 3 этапа: 1. Микросервис **ecos-apps**, увидев новый микросервис в сети, загружает из него список типов, в которых он заинтересован. 2. Получив типы, **ecos-apps** рассылает на все остальные микросервисы запрос на получение артефактов с данными типами. 3. Получив нужные артефакты со всех микросервисов, **ecos-apps** проверяет, изменился ли их контент с прошлого деплоя. Если изменений нет, то алгоритм заканчивает свою работу. Если изменения есть, то происходит деплой новых данных в целевой микросервис. **Пример артефакта. Журнал форм** .. image:: _static/arch/Apps_2.png :width: 400 :align: center Описание архитектуры событийно-ориентированного сервиса и бизнес-процессов ----------------------------------------------------------------------------- Предъявляемые требования: - **Отказоустойчивость**. При выходе из строя любого узла системы работоспособность должна сохраняться. - **Сохранность данных**. При полной или частичной потере данных на одном из узлов хранилища данные в системе не должны быть потеряны. - **Горизонтальное масштабирование**. При росте количества процессов должна быть возможность горизонтального расширения за счет увеличения количества узлов в кластере, чтобы избежать деградации времени выполнения запросов с увеличением времени жизни системы. Старые процессы, которые уже давно завершились, не должны оказывать негативное влияние на активные. Citeck Process ~~~~~~~~~~~~~~~~~~~~~~ В качестве BPM-движка для бизнес-процессов в **ecos-process** интегрировано популярное open-source решение **Camunda**. В качестве редактора для создания и редактирования процессов мы разработали свой :ref:`low-code BPMN редактор` на основе библиотеки bpmn-js, добавив туда тесную интеграцию с экосистемой Citeck (роли, формы, статусы и др). Для разработки стандартных процессов не требуется участие программистов. .. image:: _static/arch/process_1.png :width: 600 :align: center Таймеры ~~~~~~~~~ **Таймеры** в ecos-process позволяют отложить выполнение любых действий во времени. 1. Любой микросервис в системе отправляет в ecos-process команду **«Создать таймер»**, указав время срабатывания таймера и команду, которая должна при этом выполниться. 2. Когда наступает время срабатывания таймера микросервис ecos-process отправляет зарегистрированную в п.1 **команду на целевой сервис**. Целью команды может быть любой микросервис или alfresco. Примеры команд: «Отправить email», «Выполнить скрипт», «Завершить этап/задачу в процессе» и др. Кластеризация -------------- **Кластеризация** — разворачивание нескольких инстансов приложения для обработки большой нагрузки и повышения отказоустойчивости системы. Особенности: 1. Логически система работает одинаково вне зависимости от количества инстансов приложения. 2. Инстансы приложения в кластере как правило работают с одними и теми же хранилищами данных (БД, файловая система). 3. Кластеризация нужна для отказоустойчивости и распределения нагрузки по CPU, RAM и сети. Кластеризация микросервисов в системе Citeck ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. image:: _static/arch/cluster_1.png :width: 400 :align: center 1. Для разворачивания кластера микросервисов мы просто поднимаем несколько инстансов приложения. 2. При старте все приложения регистрируются в **zookeeper**, указывая при этом свой **IP**, **HOST** и **PORT**. 3. Балансировкой нагрузки занимается **ecos-gateway**. Когда приходит запрос от пользователя за некоторым ресурсом, **ecos-gateway** по информации в **zookeeper** определяет список экземпляров нужного приложения. После этого запрос уходит на один из экземпляров по алгоритму **round-robin**.