«Любой программист после пары минут чтения кода обязательно вскочит и произнесет, обращаясь к себе: переписать это все нафиг. Потом в нем шевельнется сомнение в том, сколько времени это займет, и остаток дня программист потратит на то, что будет доказывать самому себе, что это только кажется, что переписать это много работы. А если взяться и посидеть немного, то все получится. Зато код будет красивый и правильный» (с) RSDN
Наверное, многим знакомо ощущение, когда приходит время переделывать хорошо отлаженный продукт. Он работает, стабилен, предсказуем и знаком, но что-то изменилось в воздухе, выросла сложность решаемых задач, разрослась инфраструктура, появились новые вызовы, и вот приходится решительно садиться и все переделывать. В этой статье мы расскажем про эволюцию нашей системы генерации отчетов aka Отчетницы, которая прошла долгий путь за последние 15 лет. Хочется похвастаться тем, что, невзирая на соблазн взять и переделать все с нуля, вопреки эпиграфу и благодаря ряду удачных решений, развитие системы оставалось эволюционным. Участки системы, ответственные за бизнес-логику работы нашей промышленной системы, сохранялись, и это спасало человеко-месяцы и годы тестирования для другой полезной работы.
Разберемся с тем, что из себя представляют отчеты для участников рынка. Ежедневно на Московскую Биржу отправляются десятки миллионов торговых заявок, совершается несколько миллионов сделок. По результатам торговых и клиринговых сессий наши участники получают больше двух сотен отчетов об итогах торгов, оценке обеспечения, выполнении обязательств маркет-мейкеров и др. Отчеты бывают в основном торговые и клиринговые, и, соответственно, несут информацию о торгах или клиринге. На каждом из наших рынков они отличаются, хотя структурно могут хранить информацию одного типа. Отчеты рассылаются отдельно каждому участнику торгов\клиринга (включая самого главного из них – Банк России). На заре времен отчеты представляли из себя текстовые файлы с таблицами, нарисованными в псевдографике. Сейчас это XML файлы со схемами и стилями на нескольких языках. Кстати, забавный факт – по историческим причинам один из наших отчетов до сих пор отправляется в псевдографике. Ради привычки наших клиентов, которым данный формат наиболее удобен – функционал отрисовки таблиц пришлось заботливо пронести сквозь все метаморфозы системы подготовки отчетов. Впрочем, не будем забегать вперед.
В начале (примерно в 2008 году) немногочисленные отчеты генерились с помощью хранимых процедур БД (тогда еще исключительно Firebird) и настольной СУБД Corel Paradox. Это продолжалось недолго. Возня с форматированием псевдографики по мере расширения числа отчетов отнимала все больше и больше времени, так что мы переехали с псевдографики на XML. Возможность предоставлять данные отдельно от представления хоть и стоила дополнительных ресурсов на хранение структуры документа в памяти, но значительно упростила подготовку отчетов.
Вдобавок к смене формата к Paradox прикрутили продукт Altova MapForce, чтобы ввести уровень абстракции при работе с данными. Процесс подготовки отчетов стал выглядеть примерно, как на картинке (схема не наша, но концепт тот же). Маппинг данных из источника в готовый отчет теперь элегантно настраивался в несколько кликов мышки, по крайней мере на тот момент. Увы, время шло, семейство отчетов продолжало разрастаться, структура данных базы усложняться, а энтропия не убывать. Наконец настал день, когда стало ясно, что графический подход к формированию маппинга себя исчерпал. Невооруженному человеческому глазу стало сложно справляться с творящимся на экране хаосом, после чего мы сделали очередной эволюционный переход.
Стильный графический маппинг пришлось отложить в пользу удобства редактуры и повторного использования кода. Собственно маппинг, бизнес логику и сопутствующие вычисления перенесли в скриптовые файлы *.scx. Оглядываясь назад, решение оказалось исключительно удачным. Легкость редактирования скрипта и реализованный чуть позже простой, но гибкий формульный язык позволил в дальнейшем сохранять бизнес-логику формирования отчетов при значительных модификациях других частей системы. К скриптам добавили интерфейс работы с БД (все еще только Firebird), написанный на Delphi, который завернули в отдельную dll. В нее же запаковали функционал для формирования выходных данных в XML. Вокруг .scx файлов написали простые обертки на bash, чтобы можно было задать параметры вызова. Обертки используются для отладки и тестирования, а также в качестве резервного варианта подготовки отчетов при отказе каких-либо вспомогательных систем.
В таком виде система оказалась очень удобной. Здесь сказалась как гибкость Paradox, так и произведенные архитектурные доработки. Сравнительно безоблачно Отчетница провела следующие несколько лет. На их протяжении в API DLL добавились интерфейсы работы с Oracle и MS SQL, для решения ряда локальных задач появилась возможность генерировать отчеты не только в XML, но и в CSV. Проводились многократные локальные оптимизации *.scx скриптов. В рамках экспериментов по улучшению и развитию системы был сформирован уже упомянутый формульный язык, но, в целом, концепция системы изменений не претерпевала.
За несколько лет стабильности число отчетов увеличилось вдвое, объемы торгов тоже подросли. Наша торгово-клиринговая система (тогда еще ASTS), отвечая вызовам времени, постоянно повышала производительность (об этом можно почитать подробнее в наших прошлых статьях). Пыталась не отставать от нее и Отчетница. Стали сказываться проблемы, вызванные тем, что система, по сути, была клиентским приложением на рабочей машине ответственного за процедуру подготовки отчетов сотрудника (маклера). Дело в том, что по мере роста числа заявок и сделок, в какой-то момент размер xml файлов стал достигать нескольких гигабайтов и время подготовки отчетов перестало укладываться в установленные регламентом рамки. Одна машина хорошо, а три лучше - подумали мы и распараллелили процедуру подготовки отчетов. Забегая вперед, это оказался путь в никуда. По распределенным группам участников торгов отчеты формировались на 3-х, потом 4-х, потом 6-ти машинах. Это ускорило процесс подготовки, но сильно усложнило жизнь маклера. Если не вдаваться в подробности, теперь от него требовалось вдумчиво, с осознанием всех рисков, глазами и руками контролировать параллельный процесс подготовки отчетов в 6-ти терминальных вкладках.
Жить так было невозможно. Маклеров было необходимо спасать, тем более, число отчетов и заявок\сделок продолжало расти. Команда бэк-офиса взялась писать многопоточный сервер подготовки отчетов, с интеллектуальными автоматизациями в виде графов задач с вызовом скриптов по узлам (практически Application Manager), масштабируемостью, кластеризацией и аналогом BPN. И что характерно, система была написана, но в промышленную эксплуатацию не пошла. Сказался потенциально зашкаливающий объем приемочного тестирования. К сожалению, уже готовую систему пришлось отложить и вернуться к поиску решений и коробочных аналогов.
Новая архитектура
В поисках подходящих технологий мы пришли к микросервисной архитектуре и платформе Camunda. Технологии выглядели перспективными, но, в процессе реализации, мы уперлись в проблемы с производительностью библиотеки взаимодействия с БД (API dll). Чтобы их разрешить, библиотеку пришлось переписать с Delphi на .Net. Корнем всех проблем была однопоточность библиотеки, так что в новой версии она превратилась в многопроцессный и многопоточный инструмент. Это сходу уменьшило время генерации отчета примерно в три раза. Напомним, что в богатые на рыночную активность дни размер xml файлов отчетов по заявкам достигал десятков гигабайт. Таким образом, после продолжительного тестирования время формирования отчетов сократилось с более чем 60 до 20-25 минут.
После того как проблемы с .dll были решены, преград на пути обновления Отчетницы не осталось.
Теперь она представляет из себя набор микросервисов, развернутых в кластере Kubernetes. В каждый набор связанных между собой сервисов входят бэкэнд и фронтэнд сервиса формирования отчётов, бэкэнд и фронтэнд сервиса рассылки отчётов, Camunda для управления бизнес-процессом. Для реализации бэка и фронта мы выбрали .Net и React соответственно. Каждый из наборов развернут в шести экземплярах в зависимости от целевой группы (фондовый \ валютный рынок, торговые \ клиринговые операции + 2 экземпляра под внутренние нужды). Экземпляры между собой отличаются только настройками.
.SCX скрипты остались в качестве унифицированного формата описания запроса и форматирования данных. Декларативное конфигурирование обеспечивает простоту добавления новых отчетов и настройки старых. Каждый отчет по-прежнему описывается одним xml документом. Есть робкая надежда, что функционал легко расширяется без изменений в коде сервиса.
Новая архитектура существенно расширила наши возможности в автоматизации процесса подготовки отчетов. Так появились различные режимы запуска формирования отчетов: в полностью автоматическом режиме (по расписанию планировщика без участия маклера-операциониста), в полуавтоматическом (операционист в нужное время запускает формирование группы отчетов) и для проблемных случаев – полностью ручной вариант. Стало возможным формировать отчет по условию, например, по факту готовности другого отчета, либо создавать отчеты, для которых требуется подтверждение двух независимых операторов. Значительно расширились возможности аудита работы сервиса. Стал приятнее интерфейс. Все это заметно сократило трудозатраты операционистов, технической поддержки и, естественно, самих разработчиков. Существенно снизились риски совершения ошибок при ручном сопровождении процесса.
Любопытным побочным эффектом новой архитектуры стала возможность использовать Отчетницу в качестве сервера технологических операций, позволяющего подключать любые операции, выполняющиеся в течение дня, автоматически запускать группы этих операций и т. п. То есть технически ее можно использовать как инструмент для автоматизации запуска всех действий, выполняемых операционными подразделениями (на трёх рынках Мосбиржи).
Подводя итоги
За пятнадцать лет с момента создания наша Отчетница прошла долгий путь. Ограничения рождают форму и наш продукт, сталкиваясь с постоянным ростом объемов данных, увеличением сложности структуры БД, расширением бизнес-требований выкристаллизовался в масштабируемую устойчивую структуру с современным стеком технологий и высоким уровнем эргономичности. Важной заслугой на этом пути мы считаем эволюционный подход к приложению: несмотря на то, что система множество раз дорабатывалась, нам удавалось сохранить неизменными части системы с бизнес-логикой, что позволило избегать масштабного регрессионного тестирования, как в процессе разработки, так и в приемочном тестировании. Нельзя не сказать спасибо команде бэк-офиса, которая на протяжении этих пятнадцати лет с заботой и любовью совершенствовала и шлифовала напильником систему в бесконечной погоне за производительностью и удобством эксплуатации. На этом, впрочем, история Отчетницы не заканчивается. В планах дальнейшее развитие автоматизации подготовки отчетов. Запланировано импортозамещение некоторых компонент и другие работы.