XROAD
Конфигурирование системы

Основная конфигурация

Основная кoнфигурация системы состоит из набора xml файлов, расположенных в config директории. Каждому xml файлу соответствует свой xsd файл, который служит для проверки валидности конфигурации. xsd файлы расположены с config/.xsd директории. Помимо xml/xsd файлов используется dll.c исходник, который также расположен с config директории и служит для настройки роутинга сообщений в системе. Самым важным файлом конфигурации является init.xml:

<?xml version="1.0"?>
<config>
<node
wait_timeout_ms="1000"
log_level="debug"
/>
<app>
<timesheets>
<timesheet name="holidays">
<off from="00:00:00 06/12/22" till="00:00:00 06/12/22"/>
</timesheet>
</timesheets>
<schedule>
<timesheet include="holidays">
<on from="09:30:00 mon" till="23:50:00 mon"/>
<on from="09:30:00 tue" till="23:50:00 tue"/>
<on from="09:30:00 wed" till="23:50:00 wed"/>
<on from="09:30:00 thu" till="23:50:00 thu"/>
<on from="09:30:00 fri" till="23:50:00 fri"/>
</timesheet>
<nodes>
<node id="4" name="rts_exec_cgate" group="exchange" cmd="${XROAD_ROOT_DIR}/bin/rts_exec_cgate" />
<node id="5" name="moex_exec_fix" group="exchange" cmd="${XROAD_ROOT_DIR}/bin/moex_exec_fix" />
<node id="7" name="cur_exec_fix" group="exchange" cmd="${XROAD_ROOT_DIR}/bin/moex_exec_fix" />
<node id="6" name="rts_exec_fix" group="exchange" cmd="${XROAD_ROOT_DIR}/bin/rts_exec_fix" />
<node id="10" name="rts_mdata_cgate" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/rts_mdata_cgate" />
<node id="18" name="curr_ol_fast" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/mdata_fast" />
<node id="19" name="fond_ol_fast" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/mdata_fast" />
<node id="12" name="perfbot4" group="algo" />
<node id="13" name="elabhft" group="algo" />
<node id="14" name="perfbot5" group="algo" />
<node id="20" name="sitrade" group="algo" />
<node id="21" name="indicator" group="algo" config="py_algo" schema="py_algo" env="PYTHONPATH=/opt/algo/indicator1:${PYTHONPATH}" cmd="${XROAD_ROOT_DIR }/bin/py_algo -a -p /opt/algo/indicator1/basis_ema_ind_new.py"/>
</nodes>
</schedule>
<schedule>
<timesheet>
<on from="00:00:00 mon" till="23:59:59 mon"/>
<on from="00:00:00 tue" till="23:59:59 tue"/>
<on from="00:00:00 wed" till="23:59:59 wed"/>
<on from="00:00:00 thu" till="23:59:59 thu"/>
<on from="00:00:00 fri" till="23:59:59 fri"/>
<on from="09:00:00 sat" till="23:59:59 sat"/>
<on from="09:00:00 sun" till="23:59:59 sun"/>
</timesheet>
<nodes>
<node id="99" name="egate" group="tools" cmd="${XROAD_ROOT_DIR}/bin/egate" />
<node id="100" name="mail_agent" group="tools" cmd="${XROAD_ROOT_DIR}/pbin/mail_agent.py" />
<node id="101" name="ctl" group="tools" />
<node id="102" name="instr_load" group="tools" />
<node id="103" name="stat" group="tools" cmd="${XROAD_ROOT_DIR}/bin/stat" />
</nodes>
</schedule>
</app>
</config>

В этом файле определяется, какие ноды надо запустить и когда. Как видно из примера, в конфигурацию добавлены 2 секции <schedule> (9-30, 32-49). Ноды в этих секциях сгруппированы по расписанию запуска, которое задается тэгом <timesheet> (10-16, 33-41). Правило <on> задает время когда нода должна быть активной. Например,

<on from="09:30:00 mon" till="23:50:00 mon" />

говорит о том, что нода должна быть активной (в состоянии active) с 9:30 понедельника до 23:50:00 понедельника. Остальное время нода должна оставаться в состоянии offline. В тэге <nodes> задаются ноды, которые должны быть запущены. 18-24, 43-44, 47 - эти ноды запускаются при старте системы. Ноды 25-28, 45-46 не запускаются при старте системы, а запускаются вручную по усмотрению и под контролем пользователя. Возможные aтрибуты тэга <node>:

  • id - обязательный атрибут. Определяет уникальный id ноды. Используется для общения нод между собой. Id 1 зарезервирован для суперноды xroad_init
  • name - обязательный атрибут. Определяет уникальное имя ноды. При старте ноды ищется конфигурационный файл name.xml и name.xsd. Если соответствующий xml/xsd не будет найден, то нода запущена не будет.
  • group - oбязательный атрибут. Определяет группу ноды. Ноды могу быть сгруппированы логически по усмотрению пользователя. Например, по функционалу - биржевые коннекторы сгруппированы в группу exchange, коннекторы - провайдеры рыночных данных - mdata и т.д. Никакого особого функционала группировка не несет, но позволяет, например, отравить всем нодам из какой-нибудь группы сообщение
  • env - необязательный атрибут. Позволяет указать переменные окружения для запускаемой ноды. Например расширяет PYTHONPATH для ноды inicator.
  • cmd - необязательный атрибут. Определяет команду которую выполняет супернода xroad_init для запуска ноды. Если этот атрибут не задан, то нода является stand alone, т.е. не запускается при старте системы, а запускается пользователем самостоятельно
  • delay_start_s - необязательный атрибут. Определяет задержку запуска ноды в секундах
  • delay_kill_s - необязательный атрибут. Определяет задержку остановки ноды (kill signal) в секундах
  • max_restarts - необязательный атрибут. Определяет количество попыток перезапуска ноды супернодой, в случае ее падения. По умолчанию 10 раз
  • hidden - необязательный атрибут. Скрытая нода. Не отображается на WebUI
  • memory_locked - необязательный атрибут. Если атрибут установлен true, то вся выделяемая память ноды будет блокирована в ОЗУ, для предотвращения свапирования (man mlock)
  • offline_primary - необязательный атрибут. Определяет, что в primary системе нода будет оставаться offline даже если она должна активироваться исходя из расписания
  • offline_backup - необязательный атрибут. Определяет, что в backup системе нода будет оставаться offline даже если она должна активироваться исходя из расписания
  • config - необязательный атрибут. Определяет файл конфигурации для этой ноды. К примеру, для ноды с именем rts_exec_cgate должны быть определен config/rts_exec_cgate.xml. config атрибут, если он определен, задает альтернативное название конфигурации. Т.е. если config="test", для ноды rts_exec_fix будет искаться конфигурация test.xml
  • schema - необязательный атрибут. Определяет файл схемы конфигурации для этой ноды. К примеру, для ноды с именем rts_exec_cgate должна быть определена схема config/.xsd/rts_exec_cgate.xsd. schema атрибут, если он определен, задает альтернативное название схемы конфигурации. Т.е. если schema="test", для ноды rts_exec_fix будет искаться схема config/.xsd/test.xsd
  • cpus - необязательный атрибут. Задает номера CPU к которым данная нода будет прикреплена. По умолчанию "" т.е. нода будет запускаться любых cpu доступных системе. Можно указать какие-то конкретные CPUID, так и диапазоны CPUID1-CPUIDN
  • scheduler - необязательный атрибут. Определяет IO scheduler процесса. По умолчанию берется стандартный scheduler OS. Возможные значения: default, other, fifo, rr, batch, idle, deadline. См. "man sched_setscheduler"
  • sched_priority - необязательный атрибут. См. "man 7 sched"
  • nice - необязательный атрибут. Приоритет процесса. См. "man nice"

Настройка общих секций расписания

В init.xml можно отдельно указать общие части расписания и подключить их для отдельных групп нод. Для этого нужно перечислить в отдельном теге <timesheets> диапазоны c именами. В дальнейшем по имени можно подключить нужную часть расписания для группы нод через аттрибут include как это сделано для первой группы.

Переменные окружения системы

В конфигурации возможно использование переменных окружения. Переменные окружения определяются как ${variable_name}. Например:

<?xml version="1.0"?>
<config>
<node
log_level="info"
wait_timeout_ms="0"
/>
<fast_engine>
<channel name="OLI" heartbeat="40">
<feed_a address="udp://0.0.0.0;239.195.10.40:44040;91.203.253.233" recv_buf_size="1048576"/>
<feed_b address="udp://0.0.0.0;239.195.138.40:45040;91.203.255.233" recv_buf_size="1048576"/>
<recovery name="OLS" heartbeat="10" cycled_sn="true">
<feed_a address="udp://0.0.0.0;239.195.10.41:44041;91.203.253.233" recv_buf_size="1048576"/>
<feed_b address="udp://0.0.0.0;239.195.138.41:45041;91.203.255.233" recv_buf_size="1048576"/>
</recovery>
</channel>
<channel name="INI" heartbeat="40">
<feed_a address="udp://0.0.0.0;239.195.5.12:36012;91.203.253.232" recv_buf_size="1048576"/>
<feed_b address="udp://0.0.0.0;239.195.133.12:37012;91.203.255.232" recv_buf_size="1048576"/>
<recovery name="INS" heartbeat="10" cycled_sn="true">
<feed_a address="udp://0.0.0.0;239.195.5.11:36011;91.203.253.232" recv_buf_size="1048576"/>
<feed_b address="udp://0.0.0.0;239.195.133.11:37011;91.203.255.232" recv_buf_size="1048576"/>
</recovery>
</channel>
</fast_engine>
<mdata_engine filter_not_subscribed="true">
<server address="${FORTS_MD}" cpu="7"/>
</mdata_engine>
<app fix_crossed_book="false" book_levels="2" trades="true"/>
</config>

здесь используется переменная окружения FORTS_MD. В момент создания ноды производится следующая последовательность действий:

  1. конфигурация xml считывается из xml файла
  2. ищутся все переменные окружения ${var}
  3. если переменна найдена, то сначала ищется ее значение в переменных окружения OS. Если такая переменная не найдена, то она ищется в файле config/env.xml. env.xml - это специальный файл конфигурации, который является общим для всей системы, содержащий какие-то общие значения настроек. Например это могут быть значения host:port для подключения к бирже, логины, и т.д.
  4. Если значение переменной найдено, то оно подставляется в xml вместо названия переменной
  5. Если переменная не находится, то процедура чтения xml прерывается с ошибкой
  6. После того как все переменные были заменены на соответствующие значения выполняется валидация и обогащение xml при помощи xsd схемы
  7. Если шаг 6 выполнен успешно, то шаги 2-3 повторяются снова и если они завершаются успешно, то прочитанная конфигурация может использоваться дальше нодой

Добавление ноды

Предположим, что нам надо добавить ноду с именем robot в систему. Для этого необходимо выполнить следующие шаги:

  1. Убедится, что для ноды есть соответствующие xml/xsd файлы в config директории. В нашем случае это robot.xml, robot.xsd Минимальная конфигурация может выглядеть следующим образом
    robot.xml:
    <?xml version="1.0"?>
    <config>
    <node
    log_level="debug"
    />
    </config>
    robot.xsd:
    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="node.xsd"/>
    <xs:element name="config">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="node" type="node_type" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:schema>
  2. Добавить ноду в config/init.xml:
    <?xml version="1.0"?>
    <config>
    <node
    wait_timeout_ms="1000"
    log_level="debug"
    />
    <schedule>
    <timesheet>
    <on from="09:30:00 mon" till="23:50:00 mon"/>
    </timesheet>
    <nodes>
    <node id="5" name="moex_exec_fix" group="exchange" cmd="${XROAD_ROOT_DIR}/bin/moex_exec_fix" />
    <node id="10" name="rts_mdata_cgate" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/rts_mdata_cgate"/>
    <node id="11" name="curr_mdata_fast" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/moex_mdata_fast"/>
    <node id="15" name="fond_mdata_fast" group="mdata" cmd="${XROAD_ROOT_DIR}/bin/moex_mdata_fast"/>
    <node id="20" name="robot" group="algo" cmd="${XROAD_ROOT_DIR}/bin/robot"/>
    </nodes>
    </schedule>
    <schedule>
    <timesheet>
    <on from="00:00:00 mon" till="23:59:59 mon"/>
    </timesheet>
    <nodes>
    <node id="99" name="egate" group="tools" cmd="${XROAD_ROOT_DIR}/bin/egate" />
    <node id="101" name="ctl" group="tools" />
    <node id="102" name="instr_load" group="tools" />
    </nodes>
    </schedule>
    </config>
  3. Обратите внимание на строку 17. Здесь мы добавили новую ноду номер 20 с именем robot в группу algo. При старте ноды должен быть запущен исполняемый файл robot, который расположен в ${XROAD_ROOT_DIR}/bin
  4. После того как все изменения были сделаны их необходимо проверить. Для это надо запустить в консоли скрипт ./check_cfg.sh:
    ./check_cfg.sh
    ✔ build routing libraries
    ✔ check env config
    ✔ check cache config
    ✔ check init config
    ✔ check config
    
  5. Если система уже запущена, в чем можно убедится, запустив скрипт
     ./view.sh
    
    то ее надо информировать о произошедших изменениях. Это можно сделать 2-мя способами:
    • выясняем pid init ноды, например, запустив ./view.sh и посылаем -1 сигнал, используя kill:
      kill -1 12358
      
    • выполняем в консоле следующую команду из текущей директории системы (подробнее см. Интерфейс коммандной строки):
       pbin/xroad_ctl.py reconfig --node init
      
  6. Если система не была запущена, то запускаем ее скриптом start.sh
  7. После этого надо убедится, что нода была успешно запущена. Для этого запускаем
     ./view.sh
    
    скрипт и убеждаемся, что
    • нода запущена и имеет соответствующее состояние (active, inactive)
    • если нет ноды с таким именем или счетчик ошибок init ноды увеличится, это означает, что нода запущена не была
    • если нода robot появилась в списке, но статус этой ноды DEAD, это означает, что в процессе запуска ноды произошлa ошибка. Для поиска причины, почему нода не была запущена требуется посмотреть логи:
      • /var/log/syslog
      • лог ноды init
      • лог ноды, запуск которой не удался (в нашем случае data/robot/lots/XXXXXXX.log)
  8. Если требуется запустить stand alone ноду, т.е. ноду, запускаемую вручную, но при этом которая должна быть частью системы необходимо выполнить шаги 1-6, с той лишь разницей, что при добавлении ноды в config/init.xml не указывается cmd атрибут. В таком случае система только выделяет место для такой ноды в писке нод, не производя при этом запуск. Запуск самой ноды происходит вручную. Для этого надо запустить ноду с флагом -s c указанием имени ноды (в нашем случае нода называется robot)
    bin/robot -s robot
    

Удаление/остановка ноды

Для того, чтобы остановить ноду надо:

  1. закомментировать запись с добавленной нодой в config/init.xml
  2. выполнить пункты 4-5 раздела Добавление ноды
  3. убедится, что нода была остановлена, запустив скрипт
     ./view.sh.
    
    Нода в списке должна иметь статус DEAD
Note
если нода была остановлена во время работы системы, то она не удаляется из списка доступных нод. Она удаляется из списка только после остановки системы и повторного запуска с предварительной очисткой кэша системы