Broker A-MQ embedded (Resource Adapter) no JBoss EAP

Network Connector VM

O conector de transporte do tipo vm:// é usado por aplicativos Java para executar um broker embedded e se conectar a ele. Nenhuma conexão de redes é utilizada neste caso, então a comunicação entre cliente e broker acontece através de invocações de método diretamente, aumentando a performance significamente. O broker é iniciado quando a primeira conexão usando o protocolo VM é criada e as próximas conexões vindas da mesma JVM irão se conectar ao mesmo broker. Quando todas as conexões VM ao broker forem fechadas, o broker embedded será desligado automaticamente.

webconsole

Configuração do JBoss EAP 6.1

1) Baixe o JBoss EAP 6.1 diretamente do site.

2) Descompacte-o num local de sua preferência. No meu caso utilizei o /opt.

3) Edite o arquivo /opt/jboss-eap-6.1/standalone/configuration/standalone-full.xml adicionando o seguinte trecho no perfil <subsystem xmlns=”urn:jboss:domain:resource-adapters:1.1″> :

<subsystem xmlns=”urn:jboss:domain:resource-adapters:1.1″>
<resource-adapters>
<resource-adapter id=”activemq-rar-5.8.0.rar”>
<archive>
activemq-rar-5.8.0.rar
</archive>
<transaction-support>XATransaction</transaction-support>
<config-property name=”UseInboundSession”>
false
</config-property>
<config-property name=”Password”>
defaultPassword
</config-property>
<config-property name=”UserName”>
defaultUser
</config-property>
<config-property name=”ServerUrl”>
vm://localhost
</config-property>
<connection-definitions>
<connection-definition class-name=”org.apache.activemq.ra.ActiveMQManagedConnectionFactory” jndi-name=”java:jboss/ConnectionFactory” enabled=”true” pool-name=”ConnectionFactory”>
<xa-pool>
<min-pool-size>1</min-pool-size>
<max-pool-size>20</max-pool-size>
</xa-pool>
</connection-definition>
</connection-definitions>
<admin-objects>
<admin-object class-name=”org.apache.activemq.command.ActiveMQQueue” jndi-name=”java:jboss/queue/MyActiveMQQueue” use-java-context=”true” pool-name=”MyActiveMQQueue”>
<config-property name=”PhysicalName”>
QueuePhysicalName
</config-property>
</admin-object>
</admin-objects>
</resource-adapter>
</resource-adapters>
</subsystem>

Configuração do ActiveMQ Resource Adapter

1) Baixe o JBoss A-MQ diretamente do site.

O resource adapter está escondido em: extras/apache-activemq-5.8.0.redhat-60024-bin.zip/lib/optional/activemq-rar-5.8.0.redhat-60024.rar

Obs: altere a extensão de activemq-rar-5.8.0.redhat-60024.rar para activemq-rar-5.8.0.redhat-60024.zip e descompacte-o.

2) Depois de extrair o resource adapter substitua o corpo do arquivo broker-config.xml com o seguinte conteúdo:

<?xml version=”1.0″ encoding=”UTF-8″?>

<beans
xmlns=”http://www.springframework.org/schema/beans&#8221;
xmlns:amq=”http://activemq.apache.org/schema/core&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd”&gt;

<!– Embedded – load configuration file from classpath –>
<bean class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”/>

<!– shutdown hook is disabled as RAR classloader may be gone at shutdown –>
<!– Embedded – Name the broker –>
<broker xmlns=”http://activemq.apache.org/schema/core&#8221; useJmx=”true” brokerName=”JBoss.Embedded” useShutdownHook=”false”>

<managementContext>
<!– use appserver provided context instead of creating one,  for jboss use: -Djboss.platform.mbeanserver –>
<managementContext createConnector=”false”/>
</managementContext>

<persistenceAdapter>
<!– Embedded – Use the server data directory for the broker database –>
<kahaDB directory=”${jboss.server.data.dir}/kahadb”/>
</persistenceAdapter>

<transportConnectors>
<!– Embedded – The embeded broker uses the in-JVM transport, and a NIO transport is also provided.
The “nio” below may be changed – use TCP, bind to just one interface, etc..
–>
<transportConnector name=”JBoss.Embedded” uri=”vm://localhost”/>
<transportConnector name=”nio” uri=”nio://0.0.0.0:61616″/>
</transportConnectors>

</broker>
</beans>

3) No arquivo META-INF/ra.xml procure a linha e descomente:

<config-property-value>tcp://localhost:61616</config-property-value>

Em seguida, descomente a linha:

<!–config-property-value>vm://localhost</config-property-value–>

Resultado:

<!– config-property-value>tcp://localhost:61616</config-property-value –>
<config-property-value>vm://localhost</config-property-value>

4) Remova as seguintes libs do resource adapter para não haver conflito com as já existentes no EAP:

  • slf4j-api-1.6.6.jar
  • slf4j-log4j12-1.6.6.jar

5) Depois de tudo alterado, compacte o arquivo .zip e renomeie-o para activemq-rar-5.8.0.rar e o mova para /opt/jboss-eap-6.1/standalone/deployments/

Inicialização do JBoss EAP 6.1   

Neste ponto temos o JBoss EAP 6.1 com o resource adapter configurado e copiado para a pasta deployments. Para inicializá-lo com o perfil customizado execute o seguinte comando na pasta a /opt/jboss-eap-6.1/bin: 

./standalone.sh -c standalone-full.xml

Console 

19:07:35,582 INFO [org.jboss.as.messaging] (ServerService Thread Pool — 58) JBAS011601: Bound messaging object to jndi name java:/ConnectionFactory
19:07:35,583 INFO [org.jboss.as.messaging] (ServerService Thread Pool — 59) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/RemoteConnectionFactory
19:07:35,632 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-7) JBAS010406: Registered connection factory java:/JmsXA
19:07:35,666 INFO [org.hornetq.ra] (MSC service thread 1-7) HornetQ resource adaptor started
19:07:35,667 INFO [org.jboss.as.connector.services.resourceadapters.ResourceAdapterActivatorService$ResourceAdapterActivator] (MSC service thread 1-7) IJ020002: Deployed: file://RaActivatorhornetq-ra
19:07:35,670 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-2) JBAS010401: Bound JCA ConnectionFactory [java:/JmsXA]
19:07:35,830 INFO [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
19:07:35,831 INFO [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
19:07:35,831 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.1.0.GA (AS 7.2.0.Final-redhat-8) started in 3487ms – Started 154 of 216 services (61 services are passive or on-demand)
19:08:25,127 INFO [org.jboss.as.server.deployment] (MSC service thread 1-4) JBAS015876: Starting deployment of “activemq-rar-5.8.0.rar” (runtime-name: “activemq-rar-5.8.0.rar”)
19:08:25,892 INFO [org.jboss.as.connector.deployers.RADeployer] (MSC service thread 1-2) IJ020001: Required license terms for file:/opt/jboss-eap-6.1/standalone/tmp/vfs/temp188ec44f68d80f15/activemq-rar-5.8.0.rar-12de4b0407eb87cc/contents/
19:08:25,923 INFO [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-5) IJ020001: Required license terms for file:/opt/jboss-eap-6.1/standalone/tmp/vfs/temp188ec44f68d80f15/activemq-rar-5.8.0.rar-12de4b0407eb87cc/contents/
19:08:25,931 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-5) JBAS010406: Registered connection factory java:jboss/ConnectionFactory
19:08:25,937 WARN [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-5) IJ020016: Missing <recovery> element. XA recovery disabled for: java:jboss/ConnectionFactory
19:08:25,940 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-5) JBAS010405: Registered admin object at java:jboss/queue/MyActiveMQQueue
19:08:25,945 INFO [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-5) IJ020002: Deployed: file:/opt/jboss-eap-6.1/standalone/tmp/vfs/temp188ec44f68d80f15/activemq-rar-5.8.0.rar-12de4b0407eb87cc/contents/
19:08:25,950 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-1) JBAS010401: Bound JCA ConnectionFactory [java:jboss/ConnectionFactory]
19:08:25,951 INFO [org.jboss.as.connector.deployment] (MSC service thread 1-6) JBAS010401: Bound JCA AdminObject [java:jboss/queue/MyActiveMQQueue]
19:08:26,118 INFO [org.jboss.as.server] (DeploymentScanner-threads – 2) JBAS018559: Deployed “activemq-rar-5.8.0.rar” (runtime-name : “activemq-rar-5.8.0.rar”)

Producer exemplo

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
*
* @author sfantin
*
*/
public class Producer {

public void produce() throws JMSException, NamingException {
try {
// Obtain a JNDI connection
InitialContext jndi = new InitialContext();

// Look up a JMS connection factory
ConnectionFactory conFactory = (ConnectionFactory) jndi.lookup(“java:jboss/ConnectionFactory”);

// Getting JMS connection from the server and starting it
Connection connection = conFactory.createConnection();
connection.start();

// JMS messages are sent and received using a Session. We will
// create here a non-transactional session object. If you want
// to use transactions you should set the first parameter to ‘true’
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Destination destination = (Destination) jndi.lookup(“java:jboss/queue/MyActiveMQQueue”);

// MessageProducer is used for sending messages (as opposed
// to MessageConsumer which is used for receiving them)
MessageProducer producer = session.createProducer(destination);

for (int i = 0; i < 1000; i++) {
producer.send(session.createTextMessage(i + ” message”));
System.out.println(“Sent message ” + i);
}
producer.close(); session.close(); connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Obs: Assim que o primeiro produtor enviar uma mensagem para a fila MyActiveMQQueue, o message store jboss-eap-6.1/bin/activemq-data/localhost/KahaDB será criado.

MDB exemplo

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;

import org.apache.log4j.Logger;
import org.jboss.ejb3.annotation.ResourceAdapter;

/**
*
* @author sfantin
*
*/
@MessageDriven( activationConfig = {
@ActivationConfigProperty(propertyName=”destinationType”, propertyValue=”javax.jms.Queue”),
@ActivationConfigProperty(propertyName=”destination”, propertyValue=”MyActiveMQQueue”),
@ActivationConfigProperty(propertyName=”acknowledgeMode”, propertyValue=”Auto-acknowledge”)
})
@ResourceAdapter(value=”activemq-rar-5.8.0.rar”)
public class SampleMDB implements MessageListener {

private static final Logger LOG = Logger
.getLogger(SampleMDB.class);

/*
* (non-Javadoc)
* @see javax.jms.MessageListener#onMessage(javax.jms.Message)
*/
@Override
public void onMessage(final Message msg) {
LOG.log(null, msg);

System.out.println(“received message: %s” + msg);

}

}

Download do JBoss EAP 6.1 configurado

Disponibilizei o JBoss EAP com todas as configurações comentadas neste tutorial.

JBossEAP6.1.zip

Obs: o activemq-rar-5.8.0.rar pode ser encontrado dentro do diretório /jboss-eap-6.1/standalone/deployments/

Até o próximo post!


JBoss A-MQ : Produtor de mensagens utilizando protocolo fabric

Introdução

O Fuse Fabric discovery agent utiliza o protocolo fabric para a descoberta de brokers que estão em um grupo específico. Para que isto aconteça o discovery agent precisa que todos os brokers sejam implantados em somente uma fábrica. Quando um cliente tenta se conectar a um broker, o agent procura por todos os brokers disponíveis no registro do fabric e os retorna.

fabric_client

Características

  • O protocolo fabric garante failover automaticamente
  • Clientes não precisam saber onde os brokers estão localizados 
  • Funciona como o transporte failover
  • Oferece opções para reconexão:

discovery:(fabric:usa-group)?reconnectDelay=1000&useExponentialBackOff=false

  • Clientes precisam ter a URL do Zookeeper

Como configurar o broker

Para saber em detalhes como fazer o deploy de brokers utilizando o Fuse Fabric, dê uma olhada no post Cluster JBoss A-MQ : Master/Slave Network of Brokers utilizando Fuse Fabric.

 Como configurar o cliente

import javax.jms.Connection;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

public class ProducerTeste {

public static void main(String[] args) throws Exception {

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(“discovery:(fabric:usa-group)“);

Connection connection = factory.createConnection(“admin”, “admin”);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
Queue queue = session.createQueue(“SampleQueue”);
MessageProducer producer = session.createProducer(queue);

for (int i = 0; i < 1000; i++) {

producer.send(session.createTextMessage(i + ” message”));
System.out.println(“Sent message ” + i);
Thread.sleep(1000);
}
producer.close(); session.close(); connection.close();
}
}

Setando o zookeeper.url

Para que o cliente consiga encontrar corretamente o grupo de brokers, precisamos adicionar a propriedade zookeeper.url que indica a instância do Fuse Fabric’s Zookeeper, no meu caso rodando localmente adicionei no pom.xml do meu projeto:

<zookeeper.url>localhost:2181</zookeeper.url>
<zookeeper.password>admin</zookeeper.password>

Download do projeto completo

Producer-teste.zip

Até o próximo post!


Cluster JBoss A-MQ : Master/Slave Network of Brokers utilizando Fuse Fabric

Introdução

Fuse Fabric é um sistema distribuído de configuração, gerenciamento e provisionamento para Apache Karaf, Apache ActiveMQ, ServiceMix, Apache Camel para nuvem pública ou privada, que trabalha com a noção de perfis, onde cada cada perfil pode ser entendido como uma lista de configurações.
Todos os perfis são gravados no Apache Zookeeper que é um confiável coordenador de serviços distribuídos responsável por proparagar automaticamente as configurações atualizadas entre todos os nós, além de gerenciar o lock (bloqueio) de cada nó master.

Alguns benefícios:

  • Configuração centralizada entre rotas/brokers distribuídos;
  • Crescimento dinâmico o qual é essencial para ambientes de Cloud;
  • Alta Disponibilidade (HA) para aplicações de missão crítica;
  • Utiliza OGSi e Apache Karaf criação de novos brokers;
  • Provê ferramenta centralizada para configuração e monitoração (Fuse Management Console);

fabric_master_slave

Master/slave

Este tutorial mostra em detalhes como configurar e executar uma  ActiveMQ network of brokers master/slave utilizando o Fuse Management Console (FMC) para simplificar a configuração e execução dos múltiplos brokers que serão criados.
Nesta estratégia somente um broker pode ter o status master por vez, assim os slaves aguardam a parada do master para que um deles se torne o novo master.
Criar uma topologia Master-Slave with Fabric é muito fácil, basta criar múltiplos brokers em um mesmo grupo e o resto fica por conta do Fabric.
No nosso exemplo vamos criar quatro instâncias: duas USA e outras duas Japan. O primeiro broker que for iniciado será o master do seu lado, enquanto o outro será o slave.
Por default os brokers são persistentes, pois utitilizam o perfil mq-base como base.
Não é o caso deste exemplo, mas se as instâncias estiverem em máquinas separadas e utilizando storage compartilhado, precisaríamos de configurações adicionais. Por ora vamos montar o ambiente localmente.
O benefício deste tipo de configuração é que não é necessário nenhuma estratégia de lock em storage compartilhado mesmo utilizando brokers não persistentes, pois o Zookeeper garante o bloqueio dos nós master.

Obs: ainda assim há a necessidade de um message store compartilhado para que o estados dos brokers sejam garantidos.

Networks

A conexão entre os brokers dos dois grupos é especificado através da opção networks.

Instalação

1) Download

O Red Hat JBoss Fuse pode ser baixo aqui: https://www.jboss.org/products/fuse.html

Obs: disponível somente para fins de Desenvolvimento.

2) Descompactar

Descompacte o Fuse em algum lugar de sua preferência. No meu caso descopactei em /opt do meu Fedora 18.

Configuração

1) users.properties

Altere o arquivo $fuse-diretorio/etc/users.properties descomentando a linha:

#admin=admin,admin

2) system.properties

Altere o arquivo $fuse-diretorio/etc/system.properties substituindo localhost pelo hostname da máquina virtual. No meu caso é o maquina:

# Activemq configuration
activemq.port = 61616
activemq.host = maquina
activemq.url = tcp://${activemq.host}:${activemq.port}

Inicialização

Execute o seguinte arquivo $fuse-diretorio/bin 

./fuse 

fuse

Criando o cluster

Execute os seguintes comandos para criar e incializar o cluster:

1) Instala o FMC:

fabric:create -p fmc

2) Cria os dois containers usa:

fabric:container-create-child root usa 2

Jmx Login for root: admin 

Jmx Password for root: admin 

3) Cria os dois containers japan:

fabric:container-create-child root japan 2

4) O seguinte comando cria o par master/slave de brokers no grupo usa-group e o liga com os brokers japan através do linkToJapan:

fabric:mq-create --group usa-group --networks linkToJapan --networks-username admin --networks-password admin --assign-container usa1,usa2 amq-usa-profile

5) O seguinte comando cria o par master/slave de brokers no grupo japan-group e o liga com os brokers usa através do linkToUsa:

fabric:mq-create --group japan-group --networks linkToUsa --networks-username admin --networks-password admin --assign-container japan1,japan2 amq-japan-profile

6) Lista todos os clusters

fabric:cluster-list

Management Console

Acesse a seguinte URL: http://localhost:8181

1

Obs: se não estiver conseguindo acessar o Managente Console, execute o seguinte comando para instalar o FMC:  fabric:create -p fmc

No próximo post mostrarei como criar um Produtor e um Consumidor utilizando o protocolo fabric

Até o próximo post!


Cluster JBoss A-MQ : Failover em Network of Brokers – Store and Forward

Introdução

ActiveMQ suporta o conceito de Network of Brokers, onde os brokers estão remotos e as aplicações precisam de comunicar com eles de uma forma confiável. 
Na abordagem store and forward no contexto de Network of Brokers as mensagens são passadas de um broker para outro até chegar em um consumidor, onde esta mensagem estará em posse de somente um broker ao mesmo tempo, ou seja, nesta abordagen podemos garantir failover por causa do protocolo de mesmo nome, porém não podemos garantir Alta Disponibilidade (HA).
Seguindo este paradigma, ter uma arquitetura centralizada de brokers onde todos os clientes se conectam não parece uma boa ideia. Vamos supor que um broker esteja guardando uma certa quantidade de mensagens em seu persistent store e por alguma motivo ele falha. Estas mensagens estarão em posse deste broker até que ele retorne.

network_brokers_static

Solução

Utilização de Master/Slave.

Bidirecional

Por padrão esta abordagem opera somente de forma unidirecional a logicamente envia mensagens para a rede, porém uma simples configuração permite que a rede seja bidirecional onde o broker pode tanto enviar quanto receber mensagens.

Casos de Uso

  • Geralmente em grandes redes onde os produtores das mensagens estão em uma LAN e os consumidores estão em outra LAN. Neste caso pode-se usar um broker em cada LAN como se fosse um broker que irá concentrar a comunicação tentando minimizar o número de conexões entre WAN que liga as duas LANs.
  • Store and forward pode ser encontrado em ambientes de firewalls ou SSL entre redes.
  • Quando o Sistema Operacional (SO) não suporta um número grande de sockets, pode-se usar store and forward para conectar um número grande de clientes utilizando uma rede lógica.

Duas configurações

Red Hat JBoss A-MQ suporta dois diferentes tipos de configurações para formar uma Network of Brokers:

  • Static (proposta deste tutorial): onde é necessário saber o IP de todos os brokers que fazem parte da rede e inscrevê-los previamente no arquivo de configuração;
  • Multicast: utilização de Discovery para detecção automática dos brokers;

Como acessar o broker?

Clientes ActiveMQ Java e C++ provêem um protocolo de transferência chamado de failover,  que tenta se conectar automaticamente ao novo broker master sem perda de mensagens. Os clientes dos brokers utilizarão o seguinte protocolo de transporte:

failover://(tcp://host1:61616)

Dica: a URI acima irá tentar automaticamente estabelecer uma conexão com o mesmo broker no caso de queda. Portanto, mesmo que haja somente um broker no ambiente, é recomendado que o protocolo failover seja utilizado, pois no caso de queda, ele tentará se conectar novamente.

Instalação

1) Download

O Red Hat JBoss A-MQ 6.0 pode ser baixo aqui: https://www.jboss.org/products/amq.html

Obs: disponível somente para fins de Desenvolvimento.

2) Descompactar

Descompacte o A-MQ nas duas máquinas. No meu caso descopactei em /opt de cada RHEL virtual.

3) Conectividade

Tenha certeza que as máquinas conseguem se comunicar entre elas: localhost (física fazendo papel de cliente através o Fuse IDE), host1 (virtual) e host2 (virtual) e host3 (virtual).

Configurações host1

1) users.properties 

Altere o arquivo $jboss-a-mq-diretorio/etc/users.properties descomentando a linha:

#admin=admin,admin

2) system.properties

Altere o arquivo $jboss-a-mq-diretorio/etc/system.properties substituindo localhost pelo hostname da máquina virtual. No meu caso é o host1:

# Activemq configuration
activemq.port = 61616
activemq.host = host1 
activemq.url = tcp://${activemq.host}:${activemq.port}

3) activemq.xml

Altere o arquivo $jboss-a-mq-diretorio/etc/activemq.xml

<broker xmlns=”http://activemq.apache.org/schema/core&#8221;
brokerName=”amq1
useJmx=”true”
dataDirectory=”${data}”>

<managementContext>
<managementContext connectorPort=”1091” createConnector=”false”/>
</managementContext>

<networkConnectors>
<networkConnector name=“amq1:nc”
uri=”static:(failover:(tcp://host2:61616,tcp://host3:61616))”
dynamicOnly=”true”
networkTTL=”3″
duplex=”true”/>
</networkConnectors>

<persistenceAdapter>
<kahaDB directory=”${data}/kahadb”/>
</persistenceAdapter>

<plugins>
<loggingBrokerPlugin logAll=”false” logConnectionEvents=”true”/>
</plugins>

<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage limit=”20 mb”/>
</memoryUsage>
<storeUsage>
<storeUsage limit=”1 gb” name=”foo”/>
</storeUsage>
<tempUsage>
<tempUsage limit=”100 mb”/>
</tempUsage>
</systemUsage>
</systemUsage>

<transportConnectors>
<transportConnector name=”openwire” uri=”tcp://host1:61616″/>
</transportConnectors>

</broker>

Configurações host2

1) users.properties

Altere o arquivo $jboss-a-mq-diretorio/etc/users.properties descomentando a linha:

#admin=admin,admin

2) system.properties

Altere o arquivo $jboss-a-mq-diretorio/etc/system.properties substituindo localhost pelo hostname da máquina virtual. No meu caso é o host2:

# Activemq configuration
activemq.port = 61616
activemq.host = host2 
activemq.url = tcp://${activemq.host}:${activemq.port}

3) activemq.xml

<broker xmlns=”http://activemq.apache.org/schema/core&#8221;
brokerName=”amq2
useJmx=”true”
dataDirectory=”${data}”>

<managementContext>
<managementContext connectorPort=”1092” createConnector=”false”/>
</managementContext>

<persistenceAdapter>
<kahaDB directory=”${data}/kahadb”/>
</persistenceAdapter>

<plugins>
<loggingBrokerPlugin logAll=”false” logConnectionEvents=”true”/>
</plugins>

<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage limit=”20 mb”/>
</memoryUsage>
<storeUsage>
<storeUsage limit=”1 gb” name=”foo”/>
</storeUsage>
<tempUsage>
<tempUsage limit=”100 mb”/>
</tempUsage>
</systemUsage>
</systemUsage>

<transportConnectors>
<transportConnector name=”openwire” uri=”tcp://host2:61616″/>
</transportConnectors>
</broker>

Configurações host3

1) users.properties

Altere o arquivo $jboss-a-mq-diretorio/etc/users.properties descomentando a linha:

#admin=admin,admin

2) system.properties

Altere o arquivo $jboss-a-mq-diretorio/etc/system.properties substituindo localhost pelo hostname da máquina virtual. No meu caso é o host3:

# Activemq configuration
activemq.port = 61616
activemq.host = host3 
activemq.url = tcp://${activemq.host}:${activemq.port}

3) activemq.xml

<broker xmlns=”http://activemq.apache.org/schema/core&#8221;
brokerName=”amq3
useJmx=”true”
dataDirectory=”${data}”>

<managementContext>
<managementContext connectorPort=”1093” createConnector=”false”/>
</managementContext>

<persistenceAdapter>
<kahaDB directory=”${data}/kahadb”/>
</persistenceAdapter>

<plugins>
<loggingBrokerPlugin logAll=”false” logConnectionEvents=”true”/>
</plugins>

<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage limit=”20 mb”/>
</memoryUsage>
<storeUsage>
<storeUsage limit=”1 gb” name=”foo”/>
</storeUsage>
<tempUsage>
<tempUsage limit=”100 mb”/>
</tempUsage>
</systemUsage>
</systemUsage>

<transportConnectors>
<transportConnector name=”openwire” uri=”tcp://host3:61616″/>
</transportConnectors>
</broker>

Start do host1

Execute o seguinte arquivo $jboss-a-mq-diretorio/bin 

./amq 

Start do host2

Execute o seguinte arquivo $jboss-a-mq-diretorio/bin 

./amq 

Start do host3

Execute o seguinte arquivo $jboss-a-mq-diretorio/bin 

./amq 

Na maquina física

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

public class SampleClient {

public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory factory =

new ActiveMQConnectionFactory(“failover:(tcp://host1:61616)?timeout=1000“);

Connection connection = factory.createConnection(“admin”, “admin”);
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
Queue queue = session.createQueue(“SampleQueue“);
MessageProducer producer = session.createProducer(queue);

producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

// send messages
for (int i = 0; i < 100; i++) {
producer.send(session.createTextMessage(i + ” message”));
System.out.println(“Sent message ” + i);
Thread.sleep(1000);
}
producer.close(); session.close(); connection.close();
}
}

O programa acima envia 100 mensagens para o broker.

static_networkbrokers

Consumindo as mensagens

Disponibilizei logo abaixo as classes que produzem e consomem as mensagens dos brokers, além de toda configuração dos brokers.

Download de todos os recursos

  • activemq1.xml
  • activemq1.xml
  • activemq1.xml
  • Producer
  • Consumer

>>> Mensageria.zip 

Até o próximo post!


Compilando mod_jk no Fedora 18

Pré-requisitos

Instale o compilador gcc

[root@sfantin]# yum install gcc

Instale o módulo gcc-c++

[root@sfantin]# yum install gcc-c++

Instale o Apache

[root@sfantin]# yum install httpd

Compilando o mod_jk

Download do código fonte

tomcat-connectors-1.2.37-src.tar.gz

Descompactar

[root@sfantin tmp]# tar xzvf tomcat-connectors-1.2.37-src.tar.gz

Entrar no diretório

[root@sfantin tmp]# cd tomcat-connectors-1.2.37-src/native

Localize o apxs

[root@sfantin tomcat-connectors-1.2.37-src]# whereis apxs

apxs: /bin/apxs /usr/bin/apxs /usr/share/man/man1/apxs.1.gz

Execute

[root@sfantin native]# ./configure --with-apxs=/usr/bin/apxs

checking build system type… x86_64-unknown-linux-gnu
checking host system type… x86_64-unknown-linux-gnu
checking target system type… x86_64-unknown-linux-gnu
checking for a BSD-compatible install… /bin/install -c
checking whether build environment is sane… yes
checking for gawk… gawk

APRINCLUDEDIR is -I/usr/include/apr-1 -I/usr/include/apr-1
building connector for “apache-2.0”
checking for gcc… gcc -std=gnu99
checking for C compiler default output file name… a.out
checking whether the C compiler works… yes

checking for sys/stat.h… yes

checking for g++… g++
checking whether we are using the GNU C++ compiler… yes
checking whether g++ accepts -g… yes
checking dependency style of g++… none
checking how to run the C++ preprocessor… g++ -E

checking the maximum length of command line arguments… 32768
checking command to parse /bin/nm -B output from gcc -std=gnu99 object… ok
checking for objdir… .libs
checking for ar… ar
checking for ranlib… ranlib
checking for strip… strip
checking if gcc -std=gnu99 supports -c -o file.o… yes
checking whether the gcc -std=gnu99 linker (/bin/ld -m elf_x86_64) supports shared libraries… yes

checking for shl_load in -ldld… no
checking for dlopen… no
checking for dlopen in -ldl… yes
checking whether a program can dlopen itself… yes
checking whether a statically linked program can dlopen itself… yes

checking for dlopen in -ldl… (cached) yes
checking whether a program can dlopen itself… (cached) yes
checking whether a statically linked program can dlopen itself… (cached) yes
appending configuration tag “F77” to libtool
checking if libtool supports shared libraries… yes
checking whether to build shared libraries… yes
checking whether to build static libraries… yes
checking for f95 option to produce PIC… -fPIC
checking if f95 PIC flag -fPIC works… yes
checking if f95 supports -c -o file.o… yes
checking whether the f95 linker (/bin/ld -m elf_x86_64) supports shared libraries… yes
checking dynamic linker characteristics… GNU/Linux ld.so
checking how to hardcode library paths into programs… immediate
checking whether stripping libraries is possible… yes

configure: creating ./config.status
config.status: creating Makefile
config.status: creating apache-1.3/Makefile

config.status: creating common/config.h
config.status: executing depfiles commands

Execute o comando

[root@sfantin native]# make

Making all in common
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/common’
/usr/lib64/apr-1/build/libtool –silent –mode=compile gcc -std=gnu99 -I/usr/include/httpd -DHAVE_CONFIG_H -O2 -g -pipe -Wall -Wp,-

Making all in apache-2.0
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′
/usr/lib64/apr-1/build/libtool –silent –mode=compile gcc -std=gnu99 -I/usr/include/httpd -DHAVE_CONFIG_H -DUSE_APACHE_MD5 -I ../common -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m64 -mtune=generic -pthread -DHAVE_APR -I/usr/include/apr-1 -I/usr/include/apr-1 -DHAVE_CONFIG_H -pthread -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -c mod_jk.c -o mod_jk.lo
/usr/lib64/apr-1/build/libtool –silent –mode=link gcc -std=gnu99 -I/usr/include/httpd -DHAVE_CONFIG_H -DUSE_APACHE_MD5 -I ../common -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m64 -mtune=generic -pthread -DHAVE_APR -I/usr/include/apr-1 -I/usr/include/apr-1 -DHAVE_CONFIG_H -pthread -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -Wl,-z,relro,-z,now -o mod_jk.la -module -rpath /usr/lib64/httpd/modules -avoid-version mod_jk.lo ../common/jk_ajp12_worker.lo ../common/jk_connect.lo ../common/jk_msg_buff.lo ../common/jk_util.lo ../common/jk_ajp13.lo ../common/jk_pool.lo ../common/jk_worker.lo ../common/jk_ajp13_worker.lo ../common/jk_lb_worker.lo ../common/jk_sockbuf.lo ../common/jk_map.lo ../common/jk_uri_worker_map.lo ../common/jk_ajp14.lo ../common/jk_ajp14_worker.lo ../common/jk_md5.lo ../common/jk_shm.lo ../common/jk_ajp_common.lo ../common/jk_context.lo ../common/jk_url.lo ../common/jk_status.lo
../scripts/build/instdso.sh SH_LIBTOOL=’/usr/lib64/apr-1/build/libtool –silent’ mod_jk.la `pwd`
/usr/lib64/apr-1/build/libtool –silent –mode=install cp mod_jk.la /tmp/tomcat-connectors-1.2.37-src/native/apache-2.0/
libtool: install: warning: remember to run `libtool –finish /usr/lib64/httpd/modules’
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native’
make[1]: Nothing to be done for `all-am’.
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native’
target=”all”; \
list=’common apache-2.0′; \
for i in $list; do \
echo “Making $target in $i”; \
if test “$i” != “.”; then \
(cd $i && make $target) || exit 1; \
fi; \
done;
Making all in common
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/common’
make[1]: Nothing to be done for `all’.
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native/common’
Making all in apache-2.0
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′
../scripts/build/instdso.sh SH_LIBTOOL=’/usr/lib64/apr-1/build/libtool –silent’ mod_jk.la `pwd`
/usr/lib64/apr-1/build/libtool –silent –mode=install cp mod_jk.la /tmp/tomcat-connectors-1.2.37-src/native/apache-2.0/
libtool: install: warning: remember to run `libtool –finish /usr/lib64/httpd/modules’
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′

Execute o comando

[root@sfantin native]# make install

Making install in common
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/common’
make[1]: Nothing to be done for `install’.
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native/common’
Making install in apache-2.0
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′

Installing files to Apache Modules Directory…
/usr/bin/apxs -i mod_jk.la
/usr/lib64/httpd/build/instdso.sh SH_LIBTOOL=’/usr/lib64/apr-1/build/libtool’ mod_jk.la /usr/lib64/httpd/modules
/usr/lib64/apr-1/build/libtool –mode=install install mod_jk.la /usr/lib64/httpd/modules/
libtool: install: install .libs/mod_jk.so /usr/lib64/httpd/modules/mod_jk.so
libtool: install: install .libs/mod_jk.lai /usr/lib64/httpd/modules/mod_jk.la
libtool: install: install .libs/mod_jk.a /usr/lib64/httpd/modules/mod_jk.a
libtool: install: chmod 644 /usr/lib64/httpd/modules/mod_jk.a
libtool: install: ranlib /usr/lib64/httpd/modules/mod_jk.a
libtool: finish: PATH=”/usr/local/apache-maven/apache-maven-3.0.5/bin:/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/sbin” ldconfig -n /usr/lib64/httpd/modules
———————————————————————-
Libraries have been installed in:
/usr/lib64/httpd/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR’
flag during linking and do at least one of the following:
– add LIBDIR to the `LD_LIBRARY_PATH’ environment variable
during execution
– add LIBDIR to the `LD_RUN_PATH’ environment variable
during linking
– use the `-Wl,-rpath -Wl,LIBDIR’ linker flag
– have your system administrator add LIBDIR to `/etc/ld.so.conf’

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
———————————————————————-
chmod 755 /usr/lib64/httpd/modules/mod_jk.so

Please be sure to arrange /etc/httpd/conf/httpd.conf…

make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0′
make[1]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native’
make[2]: Entering directory `/tmp/tomcat-connectors-1.2.37-src/native’
make[2]: Nothing to be done for `install-exec-am’.
make[2]: Nothing to be done for `install-data-am’.
make[2]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native’
make[1]: Leaving directory `/tmp/tomcat-connectors-1.2.37-src/native’

O conector que acabou de ser criado está em:

/usr/lib64/httpd/modules/mod_jk.so

PS: dica do meu caro Raul Leite

Pronto!

 


Configurando Domain Mode no EAP 6 – RHEL/CentOS/Fedora

Domain Mode é uma das principais features do Enterprise Application Platform (EAP), pois permite o gerenciamento de toda a configuração das instâncias de um único ponto, no caso o arquivo domain.xml através do Domain Controller. Toda as instâncias gerenciadas pelo Domain Controller são chamadas de Host Controllers e podem ter suas configurações alteradas dependendo da necessidade. Podemos utilizar grupos de instâncias, assim podemos definir grupos instâncias que estão em diferentes hosts. 

domain

Obs: Vale lembrar que a utilizando Domain Mode não quer dizer que o ambiente está em Cluster, mas que todos os Host Controllers do ambiente estão compartilhando a configuração do Domain Controller.

Quando utilizamos Domain Mode três processos separados são iniciados:

  • Process Controller: responsável por gerenciar e start/restartar os processos;
  • Host Controller: um dos Host Controllers é o Domain Controller e os outros são slaves;
  • Server Instance: instância do servidor de aplicação;

Instalação

Instalação do JDK: https://serjaum.wordpress.com/2013/04/21/instalando-oracle-jdk6/

Instalação do EAP6: https://serjaum.wordpress.com/2013/04/21/instalando-eap-6/

Hosts

Neste exemplo utilizei duas máquinas virtuais com os respectivos IPs:

Nome da máquina: host1
IP: 192.168.122.1

Nome da máquina: host2
IP: 192.168.122.2

Obs: utilizei o KVM como hypervisor, que por padrão configura a comunicação entre todos as máquinas virtuais.

Dica: Se estiver utilizando o VirtualBox, segue >>> aqui <<< um tutorial que ensina como configurar a comunicação entre as máquinas envolvidas.

Precisamos fazer com que as máquinas host1 e host2 consigam se conectar entre si através do hostname.

Adicione no arquivo /etc/hosts os nomes das duas máquinas com seus respectivos IPs:

# vim /etc/hosts

192.168.122.1 host1
192.168.122.2 host2

Obs: faça a mesma alteração no host2

Desabilitando o Firewall

O próximo passo é desabilitar o firewall. Como root, execute o seguinte comando em ambas as máquinas:

# service iptables stop 

O comando acima desabilita o firewall.

# chkconfig iptables off 

O comando acima garante que o firewall não será ativado nos próximos boots.

Desabilitando o SELinux

Como root, altere nas duas máquinas o parâmetro SELINUX=enforcing para SELINUX=disabled

# vim /etc/sysconfig/selinux

Para confirmar que as duas máquinas estão se conectando entre si, tente executar o comando ping passando como parâmetro o IP da outra máquina.

No terminal da host1, digite:

$ ping host2

Execute o mesmo na host2.

Por questões didáticas, vamos alterar as instâncias da máquina host2, no arquivo host.xml:

Antes: 

<servers>
 <server name="server-one" group="main-server-group">
 <!-- Remote JPDA debugging for a specific server
 <jvm name="default">
 <jvm-options>
 <option value="-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"/>
 </jvm-options>
 </jvm>
 -->
 </server>
 <server name="server-two" group="main-server-group" auto-start="true">
 <!-- server-two avoids port conflicts by incrementing the ports in
 the default socket-group declared in the server-group -->
 <socket-bindings port-offset="150"/>
 </server>
 <server name="server-three" group="other-server-group" auto-start="false">
 <!-- server-three avoids port conflicts by incrementing the ports in
 the default socket-group declared in the server-group -->
 <socket-bindings port-offset="250"/>
 </server>
 </servers>

Depois: 

<servers>
<server name="server-four" group="main-server-group" auto-start="true">
<socket-bindings port-offset="400"/>
</server>
<server name="server-five" group="main-server-group" auto-start="true">
<socket-bindings port-offset="500"/>
</server>
</servers>

Percebam que adicionei um port-offset nas instâncias para não termos conflitos de portas. Então, para acessarmos o instância server-four temos que apontar o browser para a URL:

http://host2:8440

Para acessarmos o server-five:

http://host2:8580

Domain Controller (host1)

Na máquina host1 aponte o terminal para o diretório /opt/jboss-eap-6.0/bin e execute o seguinte comando:

$ ./add-user.sh

[user1@host1 bin]$ ./add-user.sh

What type of user do you wish to add?
a) Management User (mgmt-users.properties)
b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : master
Password : 123456
Re-enter Password :
About to add user ‘master’ for realm ‘ManagementRealm’
Is this correct yes/no? yes
Added user ‘master’ to file ‘/opt/jboss-eap-6.0/standalone/configuration/mgmt-users.properties’
Added user ‘master’ to file ‘/opt/jboss-eap-6.0/domain/configuration/mgmt-users.properties’
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value=”MTIzNDU2″ />

Iniciar o Domain Controller

Na máquina host1 aponte o terminal para o diretório /opt/jboss-eap-6.0/bin e execute o seguinte comando:

./domain.sh -b host1 -bmanagement host1

Com o EAP no ar, aponte o browser para a seguinte URL:

http://host1:9990

Username : master
Password : 123456

Na máquina host1 aponte o terminal para o diretório /opt/jboss-eap-6.0/bin e execute o seguinte comando:

[user1@host1 bin]$ ./add-user.sh

What type of user do you wish to add?
a) Management User (mgmt-users.properties)
b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : slave
Password : 123456
Re-enter Password :
About to add user ‘slave’ for realm ‘ManagementRealm’
Is this correct yes/no? yes
Added user ‘slave’ to file ‘/opt/jboss-eap-6.0/standalone/configuration/mgmt-users.properties’
Added user ‘slave’ to file ‘/opt/jboss-eap-6.0/domain/configuration/mgmt-users.properties’
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value=”MTIzNDU2″ />

Obs: o usuário “slave” será utilizado para se conectar ao master através do host2, portanto devemos definir o nome “slave” para o host2. Tal tarefa será descrita adiante.

Host Controller (host2)

Remova o arquivo /opt/jboss-eap-6.0/domain/configuration/domain.xml, pois a configuração do host1 será utilizada pelo host2. Esta é a ideia quando se monta um grupo de servidores: ter um grupo de servidores compartilhando uma única configuração, nessa caso o arquivo domain.xml do host1.

$ rm domain.xml

Altere o arquivo /opt/jboss-eap-6.0/domain/configuration/host.xml

Linha 3 aprox.)

<host name=”slave” xmlns=”urn:jboss:domain:1.3″>

Linha 36 aprox.)

<domain-controller>
<remote host=”host1″ port=”9999″ security-realm=”ManagementRealm”/>
</domain-controller>

Lembram do usuário “slave” criado na primeira máquina através do add-user.sh? Precisamos converter a senha 123456 para Base64. Há diversas maneiras para codificar uma senha, vamos utilizar o link http://www.base64online.com tal tarefa. O resultado é o seguinte:

MTIzNDU2

Obs: em versões mais novas do EAP 6, como esta que estamos utilizando, esta tarefa não é necessária, pois a senha já é convertida automaticamente assim que criamos algum usuário:

To represent the user add the following to the server-identities definition <secret value=”MTIzNDU2” />

Depois de codificar a senha para Base64, precisamos adicioná-la dentro da tag <server-identities> do arquivo host.xml do host2:

Linha 8 aprox.)

<security-realm name=”ManagementRealm”>
<server-identities>
<secret value=”MTIzNDU2” />
</server-identities>

Iniciar o Host Controller

./domain.sh -b host2 -bmanagement host2

No próximo post ensinarei como montar um cluster utilizando algumas instâncias do EAP6.


Fedora/CentOS/RHEL – Instalando o EAP 6

EAP6_installerpanel_100x360

Pré-requisito

Antes de instalarmos o EAP 6 devemos instalar o JDK.

Segue o link >>>aqui<<<.

Download e Instalação

Download do EAP 6 >>> aqui <<<:

Como root, descompacte o pacote jboss-eap-6.0.1.zip utilizando a flag -d que define o destino da pasta:

# unzip diretorio_onde_esta_o_jboss/jboss-eap-6.0.1.zip -d /opt

O comando acima descompacta o EAP 6 no diretório /opt/jboss-eap-6.0

Depois de descompactar a pasta, como root, dê permissão para que o usuário tenha acesso a todos os arquivos da pasta /opt/jboss-eap-6.0:

# chown -fR sergio. /opt/jboss-eap-6.0

Obs: sergio é o nome do meu usuário no sistema operacional

Start do EAP 6

Aponte o terminal para o diretório /opt/jboss-eap-6.0/bin e execute o seguinte comando:

./domain.xml -b host1 -bmanagement host1

Obs: host1 é o hostname da minha máquina, que pode ser visualizado com o seguinte comando:

# vim /etc/hosts

192.168.122.1 sfantin
192.168.122.146 host1
192.168.122.239 host2

Para verificar se a instalação ocorreu com sucesso, aponte o browser para a seguinte URL:

http://host1:8080

Resultado

jboss1