Некоторое время назад мне пришлось изменить стандартное поведение кластеров 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> |
И, наконец, вы можете запустить свой сервер и наслаждаться новой, классной функциональностью.