Page tree
Skip to end of metadata
Go to start of metadata

Дублирование сообщений с профилями и привязками оборудования для нескольких агентов HARD

Задача

В отдельных сегментах сети оператора используются различные схемы доступа и работают независимо друг от друга отдельные DHCP- и RADIUS-серверы. На каждом сервере установлен отдельный экземпляр агента HARD с отдельным кэшем в MongoDB. Необходимо обеспечить получение каждым агентом HARD сообщений из двух общих очередей провижининга.

Решение

Сообщения, получаемые ActiveMQ из очередей провижининга (Oracle AQ), распространяются в режиме мультикаста по нескольким собственным очередям. Каждый агент HARD работает со своей ActiveMQ-очередью и получает свою копию сообщения из провижининга.

Конфигурация маршрутов в ActiveMQ: /etc/hydra/activemq/instances-enabled/provisioning/activemq.xml
...
    <camelContext xmlns="http://camel.apache.org/schema/spring" id="camel">
        ...
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_PROFILES_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <multicast stopOnException="true">
                <to uri="activemq:queue:hydra_profiles_pppoe-rad"/>    <!-- Equipment profiles for HARD agent at PPPoE RADIUS-server -->
                <to uri="activemq:queue:hydra_profiles_ran-dhcp"/>     <!-- Equipment profiles for HARD agent at Radio Access Network DHCP-server -->
                <to uri="activemq:queue:hydra_profiles_ran-rad"/>      <!-- Equipment profiles for HARD agent at Radio Access Network RADIUS-server -->
            </multicast>
        </route>
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_EQUIPMENT_BINDS_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <multicast stopOnException="true">
                <to uri="activemq:queue:hydra_equipment_binds_pppoe-rad"/>    <!-- Equipment binds for HARD agent at PPPoE RADIUS-server -->
                <to uri="activemq:queue:hydra_equipment_binds_ran-dhcp"/>     <!-- Equipment binds for HARD agent at Radio Access Network DHCP-server -->
                <to uri="activemq:queue:hydra_equipment_binds_ran-rad"/>      <!-- Equipment binds for HARD agent at Radio Access Network RADIUS-server -->
            </multicast>
        </route>
        ...
    </camelContext>
...
Конфигурация очередей в агенте HARD на RADIUS-сервере для PPPoE: /etc/hydra/hard/hard.yml
...
# Настройки подключения к ActiveMQ
syncer:
  stomp:
    # Адрес
    host: '192.168.123.45'
    # Порт
    port: 61613
    # Имя пользователя
    login: 'hydra'
    # Пароль пользователя
    password: 'Change me please'
  queues:
    # Наименование очереди с профилями
    profiles: 'hydra_profiles_pppoe-rad'
    # Наименование очереди с привязками
    binds: 'hydra_equipment_binds_pppoe-rad'
...
Конфигурация очередей в агенте HARD на RADIUS-сервере для Radio Access Network: /etc/hydra/hard/hard.yml
...
# Настройки подключения к ActiveMQ
syncer:
  stomp:
    # Адрес
    host: '192.168.123.45'
    # Порт
    port: 61613
    # Имя пользователя
    login: 'hydra'
    # Пароль пользователя
    password: 'Change me please'
  queues:
    # Наименование очереди с профилями
    profiles: 'hydra_profiles_ran-rad'
    # Наименование очереди с привязками
    binds: 'hydra_equipment_binds_ran-rad'
...

Помещение команд с вызовом определённого скрипта в отдельную очередь

Задача

Один из используемых для провижининга оборудования скриптов работает очень медленно: например он управляет портами коммутаторов доступа по SNMP и часто отправляет команды повторно из-за отсутствия ответа коммутаторов при одной попытке. Так как очередь используется общая, команды с данным скриптом могут «тормозить» при большой нагрузке выполнение «быстрых» команд управления сессиями на BRAS'е. Необходимо отделить обработку проблемных команд от основного потока.

Решение

Сообщения с медленными командами выделяются брокером в отдельную очередь для агента HEX — обрабатываются данные сообщения независимо от остальных.

Конфигурация маршрутов в ActiveMQ: /etc/hydra/activemq/instances-enabled/provisioning/activemq.xml
...
    <camelContext xmlns="http://camel.apache.org/schema/spring" id="camel">
        ...
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_COMMANDS_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
                <choice>
                    <when>
                        <xpath>count(/command/vc_command[contains(.,'/opt/hydra/scripts/reset-switch-port.sh')]) > 0</xpath>
                        <to uri="activemq:queue:hydra_commands_reset-switch-port"/>
                    </when>
                    <otherwise>
                        <to uri="activemq:queue:hydra_commands"/>
                    </otherwise>
                </choice>
        </route>
        <route>
            <from uri="activemq:queue:hydra_command_results"/>
            <to uri="oracleTopic:topic:AIS_NET.HP_COM_RES_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
        </route>
        ...
    </camelContext>
...
Конфигурация очередей в агенте HEX: /etc/hydra/hex/hex.yml
...
hydra:
  command_queues:
    # <Очередь для приёма команд>: <Очередь для отправки результата>
    - 'hydra_commands': 'hydra_command_results'
    - 'hydra_commands_reset-switch-port': 'hydra_command_results'
...

Обновление до версии 6.3+

vc_command теперь содержит значение, закодированное в Base64. В сязи с этим команду для сравнения в xpath также нужно закодировать, например так:

Bash
echo -n "your_command" | base64

Полученный результат использовать при выборе маршрутизации <xpath>count(/command/vc_command[contains(.,'your_command_in_base64')]) > 0</xpath>

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

Команда в UTF-8Команда в Base64
prev-ip-addr: next-ip-addr: 192.168.0.1cHJldi1pcC1hZGRyOiAgbmV4dC1pcC1hZGRyOiAxOTIuMTY4LjAuMQ==
prev-ip-addr: next-ip-addr: 192.168.0.2cHJldi1pcC1hZGRyOiAgbmV4dC1pcC1hZGRyOiAxOTIuMTY4LjAuMg==
prev-ip-addr: 192.168.0.1 next-ip-addr: cHJldi1pcC1hZGRyOiAxOTIuMTY4LjAuMSBuZXh0LWlwLWFkZHI6IA==
prev-ip-addr: 192.168.0.2 next-ip-addr: cHJldi1pcC1hZGRyOiAxOTIuMTY4LjAuMiBuZXh0LWlwLWFkZHI6IA==
prev-ip-addr:cHJldi1pcC1hZGRyOg==

В данном примере можно выделить общую часть команды в Base64 — cHJldi1pcC1hZGRyO, которую и нужно использовать при маршрутизации.

Безусловное автоматическое удаление сообщений из очередей

Задача

Провижининг используется только для формирования команд по конфигурациям. RADIUS-взаимодействия нет — агент HARD не установлен. Сообщения с профилями и привязками оборудования накапливаются в очередях Oracle, напрасно занимая бесценное место в табличных пространствах.

Бизнес-хуки Гидры не используются. Сообщения копятся в очереди Oracle, занимая место в табличных пространствах

Решение

Настроить в AcitveMQ получение этих сообщений, но без сохранения их в самом брокере. Для этого в конфигурации ActiveMQ можно использовать директиву <stop/>, прерывающую маршрутизацию:

Конфигурация маршрутов в ActiveMQ: /etc/hydra/activemq/instances-enabled/provisioning/activemq.xml
...
    <camelContext xmlns="http://camel.apache.org/schema/spring" id="camel">
        <!-- Очередь команд провижининга AQ_BI_HYDRA_COMMANDS -->
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_COMMANDS_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <to uri="activemq:queue:hydra_commands_1"/>
        </route>
        <!-- Очередь результатов выполнения команд провижининга AQ_BI_HYDRA_COM_RES -->
        <route>
            <from uri="activemq:queue:hydra_command_results_1"/>
            <to uri="oracleTopic:topic:AIS_NET.HP_COM_RES_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
        </route>
        <!-- Очередь профилей AQ_BI_HYDRA_PROFILES -->
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_PROFILES_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <stop/>
            <to uri="activemq:queue:hydra_profiles_1"/>
        </route>
        <!-- Очередь привязок оборудования AQ_BI_HYDRA_EQUIP_BINDS -->
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HP_EQUIPMENT_BINDS_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <stop/>
            <to uri="activemq:queue:hydra_equipment_binds_1"/>
        </route>
        <!-- Очередь сообщений бизнес-хуков AQ_BI_HYDRA_MESSAGES -->
        <route>
            <from uri="oracleTopic:topic:AIS_NET.HYDRA_MESSAGES?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
            <stop/>
        </route>
    </camelContext>
...

Директиву to из маршрута удалять не стоит: при необходимости «включения» достаточно будет закомментировать или удалить строку с stop.
После этого все сообщения из очереди Oracle будут разбираться и удаляться исходя из RETENTION в ALL_QUEUES.

Входящая системная очередь

Задача

Гидра поддерживает механизм перевыполнения команд при записи сообщений определенного формата во входящую системную очередь (см. Запрос текущего состояния). Для записи этих сообщений в очередь удобно использовать ActiveMQ в качестве прокси, который поддерживает множество различных протоколов (STOMP, AMPQ, REST), вместо использования оракловых процедур

Решение

Настроить в AcitveMQ получение этих сообщений с отправкой в системную очередь:

Конфигурация маршрутов в ActiveMQ: /etc/hydra/activemq/instances-enabled/provisioning/activemq.xml
...
    <camelContext xmlns="http://camel.apache.org/schema/spring" id="camel">
        <route>
            <from uri="activemq:queue:hydra_input_messages_1"/>
            <to uri="oracleTopic:topic:AIS_NET.HB_SYS_IN_1?clientId=ActiveMQ&amp;durableSubscriptionName=HB"/>
        </route>
    </camelContext>
...

Выдать права для пользователя AIS_PROVISIONING для записи сообщений в системную очередь:

sqplus
BEGIN
    DBMS_AQADM.GRANT_QUEUE_PRIVILEGE(
     privilege     =>     'enqueue',
     queue_name    =>     'AIS_NET.HB_SYS_IN_1',
     grantee       =>     'AIS_PROVISIONING');
END;

 

Теперь можно отправлять сообщения в ActiveMQ. Например, можно использовать для этой цели REST API:

REST API
echo -n "body=<system_message>
    <vc_message_type>ProvisioningCurrentStateRequest</vc_message_type>
    <n_firm_id>100</n_firm_id>
    <content>
        <vc_key>Shaper-IP</vc_key>
        <vc_value>127.0.0.1</vc_value>
        <n_value />
        <d_value />
    </content>
</system_message>" | curl -u admin:admin --data-binary '@-' "http://192.168.1.1:8161/api/message/hydra_input_messages_1?type=queue"

Где Shaper-IP - название атрибута шаблона операторского профиля (IP-адрес шейпера), 127.0.0.1 - его значение, 192.168.1.1 - IP-адрес ActiveMQ.


Ускорение работы ActiveMQ

Задача

В базе сделана переотправка профилей, но ActiveMQ слишком медленно забирает сообщения из базы. Нужно ускорить работу ActiveMQ

Решение

Мы настраиваем курсор, это делается в конфиге activemq.xml

Конфигурация ActiveMQ /etc/hydra/activemq/hydra/activemq.xml
...
    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" useJmx="false" advisorySupport="false">

        <!--
            Use VM cursor
            For more information, see:
            http://activemq.apache.org/message-cursors.html
        -->
        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" producerFlowControl="true" memoryLimit="1000mb">
                  <pendingSubscriberPolicy>
                    <vmCursor />
                  </pendingSubscriberPolicy>
                </policyEntry>
                <policyEntry queue=">" producerFlowControl="true" memoryLimit="1000mb">
                  <pendingQueuePolicy>
                    <vmQueueCursor/>
                  </pendingQueuePolicy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>
...

Старые настройки можно убрать

Конфигурация ActiveMQ /etc/hydra/activemq/hydra/activemq.xml
...
    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                    <!-- The constantPendingMessageLimitStrategy is used to prevent
                         slow topic consumers to block producers and affect other consumers
                         by limiting the number of messages that are retained
                         For more information, see:

                         http://activemq.apache.org/slow-consumer-handling.html

                    -->
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>
...

Задача

Скопилась большая очередь результатов команд, ActiveMQ медленно переносит сообщения в очередь Oracle.

Решение

При отправке сообщений в очередь Oracle, ActiveMQ завершает сессию после каждого переданного сообщения. Чтобы изменить такое поведение, настроим использование пула соединений к Oracle.

Изменим URI для очереди Oracle:

Конфигурация ActiveMQ /etc/hydra/activemq/hydra/activemq.xml
...
        <route>
            <from uri="activemq:queue:hydra_command_results_1"/>
            <to uri="oraclePool:topic:AIS_NET.HP_COM_RES_1?clientId=ActiveMQ&amp;durableSubscriptionName=HP"/>
        </route>
...

И добавим описание PooledConnectionFactory после описания oracleTopic:

Конфигурация ActiveMQ /etc/hydra/activemq/hydra/activemq.xml
...
    <bean id="oracleTopic" class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory" ref="oracleTopicCredentials"/>
    </bean>

    <bean id="jmsPooledConnectionFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory"
          init-method="start" destroy-method="stop" >
        <property name="maxConnections" value="7" />
        <property name="connectionFactory" ref="oracleTopicCredentials" />
    </bean>

    <bean id="oraclePool" class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory" ref="jmsPooledConnectionFactory"/>
    </bean>
...



  • No labels