О проекте

RasEcosystem

RasEcosystem на GitHub

Это несколько приложений для администрирования кластеров 1С:Предприятия. Я начал разрабатывать их как альтернативу штатной консоли.

Изначально никакой «экосистемы» я делать не собирался. Мне хотелось получить примерно ту же консоль, только без нескольких вещей, которые постоянно мешают при работе:

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

Сначала я собирался исправить всё это в одном экспериментальном проекте. По крайней мере, так задача выглядела в начале.

Готовые сторонние инструменты для администрирования уже есть — например, ПУСК. Но мне хотелось сделать собственный open-source вариант и развивать его под свои сценарии. Отсюда отдельный API, локальная копия состояния инфраструктуры и возможность писать независимые клиенты.

Главная страница RasHub
Интерфейс одного из компонентов RasEcosystem — RasHub. Скриншот сделан в процессе разработки и может не отражать текущее состояние интерфейса.

Первый тупик — как вообще говорить с RAS

Я довольно быстро упёрся не в интерфейс и даже не в поиск. Сначала нужно было понять, как новое приложение вообще будет взаимодействовать с сервером администрирования 1С.

Для удалённого администрирования кластера в составе платформы есть сервер администрирования RAS и консольная утилита rac. Утилита rac подключается к RAS, выполняет команды администрирования и выводит результат в консоль.

У RAS всё же есть официальные программные интерфейсы — для Java и встроенного языка 1С. Но готового API для .NET нет. В моём случае прямой доступ означал бы отдельный Java-сервис или ещё одну прослойку между приложением и RAS.

Поэтому я решил начать с rac.

Сам подход выглядел криво: запускать CLI из приложения и строить поверх него свой интерфейс. С другой стороны, rac — штатная часть платформы с достаточно понятной моделью работы: аргументы командной строки, код возврата, stdout и stderr. Для первого эксперимента такой компромисс показался мне приемлемым.

Так появился RasGate.

RasGate

RasGate на GitHub

RasGate я решил оставить тонким шлюзом между приложением и rac. Gate разворачивается как отдельный сервис, а в его конфигурации указывается исполняемый файл rac. К конкретному RAS сам Gate не привязан.

Gate получает по HTTP готовый список аргументов, запускает rac, контролирует выполнение процесса и возвращает код завершения, stdout и stderr. Аргументы, включая адрес RAS, формирует вызывающая сторона. Поэтому один Gate технически может работать с несколькими доступными ему RAS.

RasGate, зарегистрированный в RasHub
RasGate, зарегистрированный в RasHub. Скриншот сделан в процессе разработки и может не отражать текущее состояние интерфейса.

При этом сам RasGate практически ничего не знает о предметной области. Он не должен понимать, что такое кластер, информационная база или сеанс с точки зрения RasEcosystem. Его задача находится уровнем ниже: превратить работу с локальным CLI в сетевой интерфейс.

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


Почему поверх Gate понадобился ещё один слой

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

Но тогда вся проблема с версиями платформы переезжала в клиент. Команды rac, их параметры и получаемые данные могут отличаться между версиями 1С. При прямой работе с Gate разбираться в этих отличиях пришлось бы каждому клиенту.

А кроме этого ему понадобится:

  • параллельно работать с несколькими Gate;
  • собирать и объединять полученные данные;
  • учитывать различия между версиями rac;
  • приводить результаты разных версий к единой модели.

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

Тащить всю эту сложность в каждый клиент мне не хотелось. Работу с несколькими Gate и совместимость версий я вынес в отдельный компонент — RasHub.

RasHub

RasHub на GitHub

Так RasHub и стал слоем между Gate и клиентами. Он знает о нескольких Gate, определяет доступную через каждый из них версию rac, формирует подходящие аргументы и приводит ответы к общей модели. Клиент выбирает зарегистрированный Gate и отправляет прикладной запрос в терминах кластеров, информационных баз и других сущностей, а не готовую команду CLI.

Потом всплыла ещё одна проблема: если каждый экран клиента всегда идёт через Gate к RAS, скорость интерфейса начинает зависеть от всей цепочки. Поэтому Hub хранит shadow-копию данных. По ней работают навигация и поиск, особенно когда запрос затрагивает несколько Gate или кластеров.

Но shadow — это всё-таки копия. Поэтому в API есть два способа получения данных. Обычные запросы читают shadow, а когда клиенту нужны свежие данные, он вызывает live-метод. Hub идёт через Gate к RAS, получает актуальное состояние и обновляет локальную копию.

Live-методы есть для списка кластеров и списка баз конкретного кластера. Поиск по нескольким Gate и кластерам работает по shadow: иначе один запрос пришлось бы превращать в обход всей инфраструктуры. Клиент сам выбирает, где ему нужны свежие данные, а где достаточно локальной копии.

Фоновые задачи RasHub
Фоновые задачи RasHub. Скриншот сделан в процессе разработки и может не отражать текущее состояние интерфейса.

RasStudio Mono

RasStudio Mono на GitHub

RasStudio Mono — экспериментальный локальный клиент на .NET, Blazor и Electron. Он запускает собственный Kestrel только на loopback-интерфейсе, хранит настройки локально в SQLite и собирается как отдельное desktop-приложение для Windows и Linux.

Клиент работает через API RasHub и не знает про запуск rac, особенности конкретной версии платформы и устройство Gate.

Интерфейс RasStudio Mono
Интерфейс экспериментального клиента RasStudio Mono. Скриншот сделан в процессе разработки и может не отражать текущее состояние интерфейса.

Где теперь проходят границы

Сейчас я разделяю ответственность так:

  • RasGate — запуск rac с готовыми аргументами и контроль процесса;
  • RasHub — формирование аргументов, совместимость версий, объединение данных и API;
  • клиент — пользовательские сценарии и интерфейс.
RasStudio Monoлокальный клиент
Другой клиентнезависимый интерфейс
API RasHub
RasHub формирует аргументы rac, учитывает версии и объединяет данные
готовые аргументы rac по HTTP
RasGate #1 исполняемый файл: rac Aможет обращаться кRAS #1RAS #2
RasGate #2 исполняемый файл: rac Bможет обращаться кRAS #3
Схема показывает логические связи, а не физическое размещение компонентов. Один RasGate может выполнять команды для нескольких доступных ему RAS.
zmaxb