Некоторое время назад мне пришлось изменить стандартное поведение кластеров 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 | importorg.jboss.msc.service.*;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.io.Serializable;importjava.util.concurrent.atomic.AtomicBoolean;publicclassMasterStatusHaSingleton     extendsAbstractService<Serializable> {  privatestaticfinalLogger LOGGER =       LoggerFactory.getLogger(MasterStatusHaSingleton.class);  privatestaticAtomicBoolean masterStatus =       newAtomicBoolean(false);  @Override  publicvoidstart(StartContext startContext) {    LOGGER.info("MasterStatusHaSingleton started");    masterStatus.set(true);  }  @Override  publicvoidstop(StopContext stopContext) {    LOGGER.info("MasterStatusHaSingleton stopped");    masterStatus.set(false);  }  publicstaticbooleanisMaster() {    returnmasterStatus.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 | packagecom.stackholder.jboss.ha;importorg.jboss.as.clustering.singleton.SingletonService;importorg.jboss.msc.service.*;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;publicclassHaSingletonActivator implementsServiceActivator {  privatefinalstaticLogger LOGGER =      LoggerFactory.getLogger(HaSingletonActivator.class);  publicstaticfinalServiceName SINGLETON_SERVICE_NAME =      ServiceName.JBOSS.append("ha", "singleton");  @Override  publicvoidactivate(ServiceActivatorContext context)       throwsServiceRegistryException {    LOGGER.info("HaSingletonActivator will be installed");    MasterStatusHaSingleton srv = newMasterStatusHaSingleton();    SingletonService singleton =         newSingletonService(srv, SINGLETON_SERVICE_NAME);    singleton.build(newDelegatingServiceContainer(        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 | <subsystemxmlns="urn:jboss:domain:ee:1.0">  <global-modules>    <modulename="org.jboss.msc"slot="main">    <modulename="org.jboss.as.clustering.singleton"slot="main">  </global-modules></subsystem> | 
И, наконец, вы можете запустить свой сервер и наслаждаться новой, классной функциональностью.