3.2.8.2. Implantação de um HA Singleton


Sumário

O procedimento a seguir demonstra como implantar um Serviço que está encapsulado com o decorador SingletonService e é usado como um serviço singleton no cluster inteiro. Este serviço ativa um timer programado, que é iniciado apenas uma vez no cluster.

Procedimento 3.21. Implantação do Serviço HA Singleton

  1. Grave o aplicativo do serviço HA singleton.

    Segue abaixo um exemplo de um Service que está encapsulado com o decorador SingletonService a ser implantado como um serviço singleton. Um exemplo completo pode ser encontrado na seção início rápido cluster-ha-singleton que é enviada junto com o Red Hat JBoss Enterprise Application Platform 6. O início rápido contém todas as instruções para a construção e implantação do aplicativo.
    1. Criação de um serviço.

      A lista abaixo é um exemplo de um serviço:
      package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;
      
      import java.util.Date;
      import java.util.concurrent.atomic.AtomicBoolean;
      
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      import org.jboss.logging.Logger;
      import org.jboss.msc.service.Service;
      import org.jboss.msc.service.ServiceName;
      import org.jboss.msc.service.StartContext;
      import org.jboss.msc.service.StartException;
      import org.jboss.msc.service.StopContext;
      
      
      /**
       * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
       */
      public class HATimerService implements Service<String> {
          private static final Logger LOGGER = Logger.getLogger(HATimerService.class);
          public static final ServiceName SINGLETON_SERVICE_NAME = ServiceName.JBOSS.append("quickstart", "ha", "singleton", "timer");
      
          /**
           * A flag whether the service is started.
           */
          private final AtomicBoolean started = new AtomicBoolean(false);
      
          /**
           * @return the name of the server node
           */
          public String getValue() throws IllegalStateException, IllegalArgumentException {
              LOGGER.infof("%s is %s at %s", HATimerService.class.getSimpleName(), (started.get() ? "started" : "not started"), System.getProperty("jboss.node.name"));
              return "";
          }
      
          public void start(StartContext arg0) throws StartException {
              if (!started.compareAndSet(false, true)) {
                  throw new StartException("The service is still started!");
              }
              LOGGER.info("Start HASingleton timer service '" + this.getClass().getName() + "'");
      
              final String node = System.getProperty("jboss.node.name");
              try {
                  InitialContext ic = new InitialContext();
                  ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).initialize("HASingleton timer @" + node + " " + new Date());
              } catch (NamingException e) {
                  throw new StartException("Could not initialize timer", e);
              }
          }
      
          public void stop(StopContext arg0) {
              if (!started.compareAndSet(true, false)) {
                  LOGGER.warn("The service '" + this.getClass().getName() + "' is not active!");
              } else {
                  LOGGER.info("Stop HASingleton timer service '" + this.getClass().getName() + "'");
                  try {
                      InitialContext ic = new InitialContext();
                      ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).stop();
                  } catch (NamingException e) {
                      LOGGER.error("Could not stop timer", e);
                  }
              }
          }
      }
      
      Copy to Clipboard Toggle word wrap
    2. Criação de um ativador que instale Service como um singleton clusterizado.

      A lista abaixo é um exemplo de um ativador de Serviço que instala HATimerService como um serviço de singleton clusterizado:
      package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;
      
      import org.jboss.as.clustering.singleton.SingletonService;
      import org.jboss.logging.Logger;
      import org.jboss.msc.service.DelegatingServiceContainer;
      import org.jboss.msc.service.ServiceActivator;
      import org.jboss.msc.service.ServiceActivatorContext;
      import org.jboss.msc.service.ServiceController;
      
      
      /**
       * Service activator that installs the HATimerService as a clustered singleton service
       * during deployment.
       *
       * @author Paul Ferraro
       */
      public class HATimerServiceActivator implements ServiceActivator {
          private final Logger log = Logger.getLogger(this.getClass());
      
          @Override
          public void activate(ServiceActivatorContext context) {
              log.info("HATimerService will be installed!");
      
              HATimerService service = new HATimerService();
              SingletonService<String> singleton = new SingletonService<String>(service, HATimerService.SINGLETON_SERVICE_NAME);
              /*
               * To pass a chain of election policies to the singleton, for example, 
               * to tell JGroups to prefer running the singleton on a node with a
               * particular name, uncomment the following line:
               */
              // singleton.setElectionPolicy(new PreferredSingletonElectionPolicy(new SimpleSingletonElectionPolicy(), new NamePreference("node2/cluster")));
      
              singleton.build(new DelegatingServiceContainer(context.getServiceTarget(), context.getServiceRegistry()))
                      .setInitialMode(ServiceController.Mode.ACTIVE)
                      .install()
              ;
          }
      }
      
      Copy to Clipboard Toggle word wrap

      Nota

      O exemplo de código acima utiliza uma classe, org.jboss.as.clustering.singleton.SingletonService, que faz parte da API privada do JBoss EAP. Uma API pública estará disponível na versão EAP 7 e a classe privada será preterida, porém estas classes serão mantidas e estarão disponíveis durante o ciclo de lançamento do EAP 6.x.
    3. Criação de um Arquivo ServiceActivator

      Crie um arquivo nomeado org.jboss.msc.service.ServiceActivator no diretório do arquivo resources/META-INF/services/. Adicione uma linha contendo um nome inteiramente qualificado da classe ServiceActivator criada na etapa anterior.
      org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.HATimerServiceActivator 
      Copy to Clipboard Toggle word wrap
    4. Criação de um bean Singleton que implementa um timer a ser usado como um timer singleton no cluster inteiro.

      Este bean Singleton não deve possuir uma interface remota e não deve haver referência à sua interface local por outro EJB em qualquer aplicativo. Isto evita uma pesquisa por parte de um cliente ou outro componente e garante que o SingletonService tenha controle total do Singleton.
      1. Criação da interface do Agendador

        package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;
        
        /**
         * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
         */
        public interface Scheduler {
        
            void initialize(String info);
        
            void stop();
        
        }
        
        Copy to Clipboard Toggle word wrap
      2. Criação de um bean do Singleton que implementa o timer do singleton amplo com cluster.

        package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;
        
        import javax.annotation.Resource;
        import javax.ejb.ScheduleExpression;
        import javax.ejb.Singleton;
        import javax.ejb.Timeout;
        import javax.ejb.Timer;
        import javax.ejb.TimerConfig;
        import javax.ejb.TimerService;
        
        import org.jboss.logging.Logger;
        
        
        /**
         * A simple example to demonstrate a implementation of a cluster-wide singleton timer.
         *
         * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
         */
        @Singleton
        public class SchedulerBean implements Scheduler {
            private static Logger LOGGER = Logger.getLogger(SchedulerBean.class);
            @Resource
            private TimerService timerService;
        
            @Timeout
            public void scheduler(Timer timer) {
                LOGGER.info("HASingletonTimer: Info=" + timer.getInfo());
            }
        
            @Override
            public void initialize(String info) {
                ScheduleExpression sexpr = new ScheduleExpression();
                // set schedule to every 10 seconds for demonstration
                sexpr.hour("*").minute("*").second("0/10");
                // persistent must be false because the timer is started by the HASingleton service
                timerService.createCalendarTimer(sexpr, new TimerConfig(info, false));
            }
        
            @Override
            public void stop() {
                LOGGER.info("Stop all existing HASingleton timers");
                for (Timer timer : timerService.getTimers()) {
                    LOGGER.trace("Stop HASingleton timer: " + timer.getInfo());
                    timer.cancel();
                }
            }
        }
        
        Copy to Clipboard Toggle word wrap
  2. Inicie cada instância do JBoss EAP 6 com o clustering habilitado.

    Para habilitar o clustering para os servidores autônomos, você deve iniciar cada servidor com o perfil HA, usando um nome de nó único e uma porta de deslocamento para cada instância.
    • Para o Linux, use a seguinte sintaxe de comando para iniciar os servidores:
      EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=UNIQUE_NODE_NAME -Djboss.socket.binding.port-offset=PORT_OFFSET
      Copy to Clipboard Toggle word wrap

      Exemplo 3.3. Inicie múltiplos servidores autônomos no Linux

      $ EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=node1
      $ EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=100
      Copy to Clipboard Toggle word wrap
    • Para o Microsoft Windows, use a seguinte sintaxe de comando para iniciar os servidores:
      EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=UNIQUE_NODE_NAME -Djboss.socket.binding.port-offset=PORT_OFFSET
      Copy to Clipboard Toggle word wrap

      Exemplo 3.4. Inicie múltiplos servidores autônomos no Microsoft Windows

      C:> EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=node1
      C:> EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=100
      Copy to Clipboard Toggle word wrap

    Nota

    Caso decida por não usar os argumentos da linha de comando, o arquivo standalone-ha.xml pode ser configurado para cada instância do servidor para vincular a uma interface separada.
  3. Implante o aplicativo nos servidores

    O comando Maven a seguir implanta o aplicativo em um servidor autônomo executando nas portas padrões.
    mvn clean install jboss-as:deploy
    Copy to Clipboard Toggle word wrap
    Para a implantação de servidores adicionais, passe o nome do servidor. Caso esteja em um host diferente, passe o nome do host e o número da porta na linha de comando:
    mvn clean package jboss-as:deploy -Djboss-as.hostname=localhost -Djboss-as.port=10099
    Copy to Clipboard Toggle word wrap
    Consulte a seção início rápido cluster-ha-singleton, que é enviada junto com o JBoss EAP 6, para mais detalhes sobre a configuração e implantação do Maven.
Red Hat logoGithubredditYoutubeTwitter

Aprender

Experimente, compre e venda

Comunidades

Sobre a documentação da Red Hat

Ajudamos os usuários da Red Hat a inovar e atingir seus objetivos com nossos produtos e serviços com conteúdo em que podem confiar. Explore nossas atualizações recentes.

Tornando o open source mais inclusivo

A Red Hat está comprometida em substituir a linguagem problemática em nosso código, documentação e propriedades da web. Para mais detalhes veja o Blog da Red Hat.

Sobre a Red Hat

Fornecemos soluções robustas que facilitam o trabalho das empresas em plataformas e ambientes, desde o data center principal até a borda da rede.

Theme

© 2026 Red Hat
Voltar ao topo