Статьи

Использование HA Singleton в JBoss 7

Некоторое время назад мне пришлось изменить стандартное поведение кластеров 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>

И, наконец, вы можете запустить свой сервер и наслаждаться новой, классной функциональностью.

Ссылка: Использование HA Singleton в JBoss 7 от нашего партнера по JCG Якуба Кубрински в блоге Java (B) Log .