Некоторое время назад мне пришлось изменить стандартное поведение кластеров Quartz Scheduler и позволить ему работать без синхронизации по базе данных. Конечно, есть много вариантов сделать это, но, поскольку я большой поклонник простоты, я решил использовать стандартную конфигурацию Spring @Scheduled и полностью пропустить размышления о кластере на этом уровне. Идея состояла в том, чтобы просто вызвать метод «проверьте, что я нахожусь на главном узле» в начале запланированного метода. Единственная проблема заключалась в том, как написать такой метод. Выбор заключался в использовании функциональности JBoss HA Singleton. Он доступен в JBoss 7.x, но большой недостаток документации вызывает некоторые эксперименты … приятно!
Первое, что нам нужно сделать, это обеспечить правильную зависимость, содержащую несколько важных классов. Конечно, помните о правильной версии (здесь я использую 7.1.1.Final, потому что она доступна в публичных репозиториях и все последующие версии 7 должны быть собраны вручную).
1
2
3
4
5
6
|
< dependency > < groupid >org.jboss.as</ groupid > < artifactid >jboss-as-clustering-singleton</ artifactid > < version >7.1.1.Final</ version > < scope >provided</ scope > </ dependency > |
Теперь пришло время заняться кодированием! Начнем с класса, содержащего сервис, который будет установлен на сервер приложений. Его роль состоит в том, чтобы установить главный флаг статуса и выставить его простым статическим методом.
пакет com.stackholder.jboss.ha;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import org.jboss.msc.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.concurrent.atomic.AtomicBoolean; public class MasterStatusHaSingleton extends AbstractService<Serializable> { private static final Logger LOGGER = LoggerFactory.getLogger(MasterStatusHaSingleton. class ); private static AtomicBoolean masterStatus = new AtomicBoolean( false ); @Override public void start(StartContext startContext) { LOGGER.info( "MasterStatusHaSingleton started" ); masterStatus.set( true ); } @Override public void stop(StopContext stopContext) { LOGGER.info( "MasterStatusHaSingleton stopped" ); masterStatus.set( false ); } public static boolean isMaster() { return masterStatus.get(); } } |
Теперь нам нужно написать класс, который установит подготовленный сервис в контейнер.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.stackholder.jboss.ha; import org.jboss.as.clustering.singleton.SingletonService; import org.jboss.msc.service.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HaSingletonActivator implements ServiceActivator { private final static Logger LOGGER = LoggerFactory.getLogger(HaSingletonActivator. class ); public static final ServiceName SINGLETON_SERVICE_NAME = ServiceName.JBOSS.append( "ha" , "singleton" ); @Override public void activate(ServiceActivatorContext context) throws ServiceRegistryException { LOGGER.info( "HaSingletonActivator will be installed" ); MasterStatusHaSingleton srv = new MasterStatusHaSingleton(); SingletonService singleton = new SingletonService(srv, SINGLETON_SERVICE_NAME); singleton.build( new DelegatingServiceContainer( context.getServiceTarget(),context.getServiceRegistry())) .setInitialMode(ServiceController.Mode.ACTIVE).install(); LOGGER.info( "HaSingletonActivator installation SUCCESSFUL" ); } } |
Помните, что JBoss 7 использует OSGi, поэтому мы должны сообщить серверу приложений, какие модули мы будем использовать в нашем приложении. Самый простой способ сделать это — добавить конфигурацию в плагин war или jar:
01
02
03
04
05
06
07
08
09
10
|
< configuration > < archive > < manifestentries > < dependencies > org.jboss.msc,org.jboss.as.server, org.jboss.as.clustering.singleton </ dependencies > </ manifestentries > </ archive > </ configuration > |
Отлично — почти закончено! Почти. Последнее, что нам нужно сделать, это активировать соответствующие модули в конфигурации JBoss. Просто отредактируйте файл standalone-full-ha.xml (или другую используемую вами конфигурацию) и добавьте следующие модули в подсистему ee:
1
2
3
4
5
6
|
< subsystem xmlns = "urn:jboss:domain:ee:1.0" > < global-modules > < module name = "org.jboss.msc" slot = "main" > < module name = "org.jboss.as.clustering.singleton" slot = "main" > </ global-modules > </ subsystem > |
И, наконец, вы можете запустить свой сервер и наслаждаться новой, классной функциональностью.