1. Установка ServiceMix 7.0.1
Описано в статье Установка Apache ServiceMix 7.0.1 на сервере Ubuntu 16.04 LTS
2. Подключение репозитория Cellar
Для Karaf 4.0.9, который входит в состав ServiceMix 7.0.1, предназначена версия Cellar 4.0.4 (последняя на момент написания статьи).
Для ее установки необходимо подключить репозиторий
karaf@root> feature:repo-add cellar 4.0.4
3. Установка Cellar
karaf@root> feature:install cellar
karaf@root> cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
x | 192.168.114.9:5701 | | 192.168.114.9 | 5701
Необходимо установить Cellar на всех узлах, предполагаемых для использования в кластере. В моем случае это будут узлы:
192.168.114.9
10.1.1.43
10.1.1.44
Видно, что два узла находятся в одной подсети, а третий - в отдельной.
4. Настройка кластера в случае нескольких физических подсетей
Apache Karaf Cellar по-умолчанию использует протокол multicast (с помощью библиотеки hazelcast) для автоматического поиска узлов в текущей подсети. Действительно, сразу после установки два из моих узла "увидели" друг друга, а третий - остался незамеченным.
для 192.168.114.9:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
x | 192.168.114.9:5701 | | 192.168.114.9 | 5701
для 10.1.1.43:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
| 10.1.1.44:5701 | | 10.1.1.44 | 5701
x | 10.1.1.43:5701 | | 10.1.1.43 | 5701
для 10.1.1.44:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
x | 10.1.1.44:5701 | | 10.1.1.44 | 5701
| 10.1.1.43:5701 | | 10.1.1.43 | 5701
Но мне было необходимо создать один кластер из трех узлов.
Для этого потребуется настроить hazelcast на поиск узлов по TCP/IP. В последних версиях Cellar возможна работа лишь в одном из режимов поиска узлов: либо multicast, либо tcp/ip. Поэтому изменим в файле-конфигурации настройки: etc/hazelcast.xml (путь относительно установленного ServiceMix или Karaf)
...
<hz:network>
...
<hz:join>
<hz:multicast enabled="false">
<hz:multicast-group>224.2.2.3</hz:multicast-group>
<hz:multicast-port>54327</hz:multicast-port>
</hz:multicast>
<hz:tcp-ip enabled="true">
<hz:interface>192.168.114.9</hz:interface>
<hz:interface>10.1.1.43</hz:interface>
<hz:interface>10.1.1.44</hz:interface>
</hz:tcp-ip>
...
Выключим multicast <hz:multicast enabled="false">
, включим tcp/ip <hz:tcp-ip enabled="true">
и прописать явно список узлов, входящих в кластер.
После перезапуска самого Karaf спустя несколько секунд кластер смог увидеть все ноды.
для 192.168.114.9:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
| 10.1.1.44:5701 | | 10.1.1.44 | 5701
| 10.1.1.43:5701 | | 10.1.1.43 | 5701
x | 192.168.114.9:5701 | | 192.168.114.9 | 5701
для 10.1.1.43:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
| 10.1.1.44:5701 | | 10.1.1.44 | 5701
x | 10.1.1.43:5701 | | 10.1.1.43 | 5701
| 192.168.114.9:5701 | | 192.168.114.9 | 5701
для 10.1.1.44:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
x | 10.1.1.44:5701 | | 10.1.1.44 | 5701
| 10.1.1.43:5701 | | 10.1.1.43 | 5701
| 192.168.114.9:5701 | | 192.168.114.9 | 5701
5. Механизм синхронизации кластера Cellar
После создания кластера Cellar в конфигурации по-умолчанию все его узлы равнозначны. Это значит, что любые изменения синхронизируемых объектов после их внесения на одном узле сразу распространяются и на другие узлы кластера.
Кластер Cellar может синхронизировать следующие типы объектов Karaf :
- Конфигурация (настройки)
- Bundle-ы (бандлы - пользовательские приложения)
- KAR (к сожалению, мне пока не удалось найти документацию по этому типу объектов)
- Репозитории Feature-ов
- Feature-ы (фичеры - модули Karaf)
Связь (обмен) между узлами кластера Cellar можно представить в виде схемы:
Каждый узел может выступать в роли:
- Producer - поставщик событий
- Consumer - потребитель событий
- Event Handler - обработчик событий
Таким образом, когда в один из узлов вносятся изменения какого-либо объекта синхронизации (конфигурация, бандлы, фичеры и др.), этот узел рассылает (producer) сообщение о событии всем остальным узлам. В свою очередь, остальные узлы принимают (consumer) это сообщение и передают в соответствующий обработчик (event handler). Этим механизмом поддерживается идентичность узлов кластера Cellar.
6. Управление ролями узлов кластера Cellar
Настройки хранятся в файле конфигурации etc/org.apache.karaf.cellar.node.cfg
Для просмотра состояния ролей узла можно выполнить следующие команды:
karaf@root>cluster:producer-status
| Node | Status
-------------------------------
| 10.1.1.44:5701 | ON
| 10.1.1.43:5701 | ON
x | 192.168.114.9:5701 | ON
karaf@root>cluster:consumer-status
| Node | Status
-------------------------------
| 10.1.1.44:5701 | ON
| 10.1.1.43:5701 | ON
x | 192.168.114.9:5701 | ON
karaf@root>cluster:handler-status
| Node | Status | Event Handler
------------------------------------------------------------------------------------------
| 10.1.1.44:5701 | ON | org.apache.karaf.cellar.bundle.BundleEventHandler
| 10.1.1.44:5701 | ON | org.apache.karaf.cellar.config.ConfigurationEventHandler
| 10.1.1.44:5701 | ON | org.apache.karaf.cellar.kar.KarEventHandler
| 10.1.1.44:5701 | ON | org.apache.karaf.cellar.features.RepositoryEventHandler
| 10.1.1.44:5701 | ON | org.apache.karaf.cellar.features.FeaturesEventHandler
| 10.1.1.43:5701 | ON | org.apache.karaf.cellar.bundle.BundleEventHandler
| 10.1.1.43:5701 | ON | org.apache.karaf.cellar.config.ConfigurationEventHandler
| 10.1.1.43:5701 | ON | org.apache.karaf.cellar.kar.KarEventHandler
| 10.1.1.43:5701 | ON | org.apache.karaf.cellar.features.FeaturesEventHandler
| 10.1.1.43:5701 | ON | org.apache.karaf.cellar.features.RepositoryEventHandler
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.config.ConfigurationEventHandler
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.bundle.BundleEventHandler
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.kar.KarEventHandler
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.features.RepositoryEventHandler
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.features.FeaturesEventHandler
Видно, что роли Producer и Consumer задаются на целый узел, а обработчики события - на каждый тип объекта.
Управление ролями заключается в том, что путем настроек можно оставить работающими определенный набор ролей, а остальные - выключить.
Выключение ролей:
karaf@root>cluster:producer-stop
| Node | Status
-------------------------------
x | 192.168.114.9:5701 | OFF
karaf@root>cluster:consumer-stop
| Node | Status
-------------------------------
x | 192.168.114.9:5701 | OFF
karaf@root>cluster:handler-stop org.apache.karaf.cellar.bundle.BundleEventHandler
| Node | Status | Event Handler
-----------------------------------------------------------------------------------
x | 192.168.114.9:5701 | OFF | org.apache.karaf.cellar.bundle.BundleEventHandler
Включение ролей:
karaf@root>cluster:producer-start
| Node | Status
-------------------------------
x | 192.168.114.9:5701 | ON
karaf@root>cluster:consumer-start
| Node | Status
-------------------------------
x | 192.168.114.9:5701 | ON
karaf@root>cluster:handler-start org.apache.karaf.cellar.bundle.BundleEventHandler
| Node | Status | Event Handler
-----------------------------------------------------------------------------------
x | 192.168.114.9:5701 | ON | org.apache.karaf.cellar.bundle.BundleEventHandler
В добавок к этому есть возможность из консоли одного узла управлять ролями другого узла. Для этого в конце каждой команды следует указать узел, например:
karaf@root>cluster:node-list
| Id | Alias | Host Name | Port
-----------------------------------------------------
| 10.1.1.44:5701 | | 10.1.1.44 | 5701
| 10.1.1.43:5701 | | 10.1.1.43 | 5701
x | 192.168.114.9:5701 | | 192.168.114.9 | 5701
karaf@root>cluster:producer-stop 10.1.1.44:5701
| Node | Status
---------------------------
| 10.1.1.44:5701 | OFF
karaf@root>cluster:producer-status
| Node | Status
-------------------------------
| 10.1.1.44:5701 | OFF
| 10.1.1.43:5701 | ON
x | 192.168.114.9:5701 | ON
karaf@root>cluster:producer-start 10.1.1.44:5701
| Node | Status
---------------------------
| 10.1.1.44:5701 | ON
7. Выделение групп узлов кластера Cellar
Узлы кластера Cellar можно поделить по группам. В таком случае сообщения о событиях будут приниматься теми узлами, которые входят в состав группы. По-умолчанию все узлы добавляются в группу default. Это единственная группа, которая всегда есть, и ее нельзя удалить, т.к. она используется как шаблон для создания других групп.
karaf@root>cluster:group-list
| Group | Members
------------------------------------------------------------------
x | default | 10.1.1.43:5701 10.1.1.44:5701 192.168.114.9:5701(x)
Видно, что все три мои узла находятся в составе группы по-умолчанию default.
Создадим группу test и перенесем в нее один узел. Стоит отметить, что перенести в группу можно только тот узел, в чьей консоли выполняются команды (в отличие от управления ролями).
karaf@root>cluster:group-create test
karaf@root>cluster:group-list
| Group | Members
------------------------------------------------------------------
| test |
x | default | 10.1.1.43:5701 10.1.1.44:5701 192.168.114.9:5701(x)
karaf@root>cluster:group-join test
| Group | Members
------------------------------------------------------------------
x | test | 192.168.114.9:5701(x)
x | default | 10.1.1.43:5701 10.1.1.44:5701 192.168.114.9:5701(x)
karaf@root>cluster:group-quit default
| Group | Members
--------------------------------------------
x | test | 192.168.114.9:5701(x)
| default | 10.1.1.43:5701 10.1.1.44:5701
В такой настройке состояние узла 192.168.114.9:5701
не будет синхронизировано с остальными двумя узлами, т.к. они теперь находятся в разных группах.
Возврат к исходному состоянию:
karaf@root>cluster:group-join default
| Group | Members
------------------------------------------------------------------
x | test | 192.168.114.9:5701(x)
x | default | 10.1.1.43:5701 10.1.1.44:5701 192.168.114.9:5701(x)
karaf@root>cluster:group-quit test
| Group | Members
------------------------------------------------------------------
| test |
x | default | 10.1.1.43:5701 10.1.1.44:5701 192.168.114.9:5701(x)
karaf@root>cluster:group-delete test
Стоит с осторожностью распределять узлы по группам, т.к. есть одна особенность, которую хочется затронуть.
7.1 Перекрытие групп узлов
Если создать конфигурацию групп узлов, показанную на рисунке, и произвести изменения, например, бандла в узле NodeA, то произойдут следующие миграции изменений:
- Поскольку NodeA и NodeB объединены в одну группу CG1, то бандл установится на узел NodeB
- Поскольку NodeB и NodeD объединены в одну группу CG3, то бандл установится на узел NodeD
- Поскольку NodeD и NodeC объединены в одну группу CG2, то бандл установится на узел NodeC
Таким образом, бандл будет установлен на все узлы кластера, несмотря на то, что явным образом все узлы не находятся в единой группе.
8. Примеры топологии узлов кластера
Типичными примерами топологии узлов кластера Cellar являются топологии в виде Креста и в виде Звезды.
8.1 Топология Крест
В этой топологии Cellar устанавливается на все узлы в одинаковой конфигурации ролей (Producers, Consumers, Event handlers) - все роли включены. Изменения могут вноситься в любой узел, распространяются на все узлы.
8.2 Топология Звезда
В этой топологии Cellar устанавливется на все узлы, но роль Producer должна быть включена только на одном узле - этот узел будет выступать в роли менеджера кластера. Изменения должны вноситься в этом узле, они будут распространены на все остальные узлы. Любые изменения на "управляемых" узлах не будут транслированы на кластер.