Dispositivos móveis: a interface com o mundo

Republicação de Boris Kuszka:

Todos vocês já devem ter se deparado com as estatísticas mais recentes de queda de venda de PCs (desktops) com a vinda de telefones inteligentes (smartphones), tablets, híbridos de tablet e smartphone, Ultrabooks, e-readers com acesso à internet, etc. Isso é na verdade o que a indústria está definindo no meio corporativo de BYOD (Bring Your Own Device, ou traga o seu próprio dispositivo), ou seja, você escolhe a forma como quer acessar os seus aplicativos: usar seu banco, comprar ingressos, fazer compras em geral e até mesmo acessar os sistemas da empresa em que trabalha com o seu dispositivo móvel.
O acesso via dispositivos móveis pode ser analisado por meio de duas visões: a corporativa e a privada. Apesar do dispositivo ser o mesmo que você usa para acessar sua empresa e seus dados pessoais, as formas como isso se desenvolveu em cada um dos casos foram bem distintas.

39794.56852-no-celular
A visão corporativa

Como chegamos no BYOD? Vale voltarmos alguns anos para revermos como isso evoluiu e como isso impacta em termos de inovação.

Nos anos 60 até 80, na era dos mainframes, o acesso era feito por meio dos terminas síncronos, de tamanho e peso gigantescos, normalmente de fósforo verde, sem gráficos. Todo processamento era centralizado no data center, o que permitia um controle total para quem administra os sistemas, mas com pouquíssima flexibilidade. Se por qualquer razão você precisasse acessar qualquer sistema, tinha que correr para o escritório/fábrica e chegar ao terminal para acessar os aplicativos da empresa.

No final dos anos 80, surgiram os equipamentos baseados em processador RISC e sistema operacional UNIX, e foi aí que começou a era do downsizing, que foi a migração do mainframe para equipamentos baseados em padrões abertos, os chamados “Open Systems”, principalmente por razões de custos e possibilidade de ficar um pouco menos dependente do fabricante; afinal de contas, o UNIX prometia uma plataforma aberta e intercambiável, coisa que nunca aconteceu em sua plenitude. E esforços de migração entre UNIX continuam ocorrendo até hoje. Nessa época, o acesso era feito por terminais assíncronos, o que pelo menos nos dava a opção de acesso via MODEM (acesso pela linha telefônica) e assim, de forma ainda mais interessante, começou uma nova arquitetura computacional chamada de cliente-servidor, na qual o acesso era feito por um PC – uma parte da aplicação rodava nesse PC e outra no servidor.

Isso durou até o final dos anos 90, quando veio a internet, a plataforma Java (rode seu aplicativo de qualquer dispositivo, de qualquer lugar, com segurança” dizia o slogan do Java, coisa que em larga escala efetivamente começamos a ver hoje em dia). O famoso slogan da falecida Sun Microsystems finalmente começou a fazer sentido: “a rede é o computador”. Arquiteturas novas que permitiam acessar os servidores do data center via navegadores (na época tínhamos principalmente o Netscape e o Internet Explorer) e, para os sistemas legados, havia o acesso via VDI (desktop virtual) em que você mostrava a tela do aplicativo via outros dispositivos, como PCs, “thin clients” e, com algumas restrições, celulares.

Boris Kuszka é o Diretor dos Arquitetos de Solução da Red Hat. Possui 22 anos de experiência em tecnologia da informação, sempre atuou na área de Open Systems passando por empresas como IBM, Sun Microsystems, Nokia, Oracle, HP e NetApp. É formado em Engenharia Eletrônica pela Politécnica/USP e especializado em diversos cursos e treinamentos na área de TI.

Matéria completahttp://corporate.canaltech.com.br/coluna/mobile/Dispositivos-moveis-a-interface-com-o-mundo/ 


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 : Consumidor 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_consumer

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

Para saber em detalhes como criar um client que envia mensagens para o Fuse Fabric, dê uma olhada no post JBoss A-MQ : Produtor de mensagens utilizando protocolo fabric.

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

Consumer-teste.zip

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 : 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!


Cluster JBoss A-MQ : Master/Slave com File System compartilhado

Introdução

O ponto fundamental desta abordagem é prover Alta Disponibilidade (HA) em cenários de produção utilizando ActiveMQ. Na configuração master/slave existe somente um broker Master e vários slaves aguardando a falha do master para serem promovidos, na verdade somente um será. A falha do master é detectada pela falta de conectividade entre o master e os slaves.
masterslave

Duas configurações

A versão 6.0 do Red Hat JBoss A-MQ suporta dois diferentes tipos de configurações master/slave:

  • Shared nothing, onde cada broker ActiveMQ tem seu próprio message storage;
  • Shared storage (proposta deste tutorial), onde múltiplos brokers ActiveMQ brokers podem se contectar ao message store (banco relacional ou sistema de arquivos) compartilhado mas somente um broker estará ativo ao mesmo tempo. Nenhum intervenção manual é requerida para manter a integridade de aplicação. Nenhum limitação de número de brokers slave. O master terá o lock do DB.

Três tipos de Message Stores

  1. File System Master Slave compartilhado: por exemplo SAN, NFS, etc.
  2. JDBC Master Slave:  Um banco de dados compartilhado. Não é a melhor opção tem termos de performance porque não utiliza journal de alta performance, mas a configuração é bem simples.

Por que usar File System ao invés de Banco de Dados?

Utilizar file system compartilhado é a melhor solução para prover Alta Disponibilidade, pois combina o alto throughput do KahaDB e a simplicidade de se utilizar um recurso compartilhado. KahaDB é extremamente rápido e é limitado somente pela performance do file system.
Não é necessário configuração adicional dos brokers e não existe limite de slaves acessando o file system.

Neste tutorial utilizarei o Network File System (NFS) como file system compartilhado, porém poderia ter escolhido outros como Global File System (GFS) 2 ou Storage Area Network (SAN).

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,tcp://host2:61616)?randomize=false

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), host1 (virtual) e host2 (virtual).

4) Diretório compartilhado

Criei um /shared na minha máquina física utilizando NFS e o exportei para as máquinas virtuais: host1 e host2

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=”broker_host1
dataDirectory=”${data}”
useJmx=”true”
start=”false”>

<transportConnectors>
<!– Na perspectiva do cliente a uri é usada para criar uma conexão com o broker para enviar/receber mensages –>
<transportConnector name=”openwire” uri=”tcp://host1:61616″/>
</transportConnectors>

<persistenceAdapter>
<kahaDB directory=“/shared“>
</persistenceAdapter>

<managementContext>
<managementContext createConnector=”trueconnectorPort=”1091″/>
</managementContext>

Obs: coloquei somente os trechos alterados.

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

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

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

<transportConnectors>
<!– Na perspectiva do cliente a uri é usada para criar uma conexão com o broker para enviar/receber mensages –>
<transportConnector name=”openwire” uri=”tcp://host2:61616″/>
</transportConnectors>

<persistenceAdapter>
<kahaDB directory=“/shared“>
</persistenceAdapter>

<managementContext>
<managementContext createConnector=”true” connectorPort=”1092″/>
</managementContext>

Obs: coloquei somente os trechos alterados.

Start do host1

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

./amq 

Console host1

2013-11-05 12:26:30,843 | INFO | veMQ Broker: amq | PListStoreImpl | tore.kahadb.plist.PListStoreImpl 331 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | PListStore:[/opt/jboss-a-mq-6.0.0.redhat-024/data/amq/broker_host1/tmp_storage] started
2013-11-05 12:26:31,004 | INFO | JMX connector | ManagementContext | q.broker.jmx.ManagementContext$1 138 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1091/jmxrmi
2013-11-05 12:26:31,016 | INFO | veMQ Broker: amq | BrokerService | he.activemq.broker.BrokerService 595 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Using Persistence Adapter: KahaDBPersistenceAdapter[/shared]
2013-11-05 12:26:32,252 | INFO | veMQ Broker: amq | MessageDatabase | .kahadb.MessageDatabase$Metadata 147 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | KahaDB is version 4
2013-11-05 12:26:32,264 | INFO | veMQ Broker: amq | MessageDatabase | emq.store.kahadb.MessageDatabase 552 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Recovering from the journal …
2013-11-05 12:26:32,265 | INFO | veMQ Broker: amq | MessageDatabase | emq.store.kahadb.MessageDatabase 565 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Recovery replayed 1 operations from the journal in 0.009 seconds.
2013-11-05 12:26:32,403 | INFO | veMQ Broker: amq | BrokerService | he.activemq.broker.BrokerService 634 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Apache ActiveMQ 5.8.0.redhat-60024 (broker_host1, ID:host1-60970-1383672392281-0:1) is starting
2013-11-05 12:26:32,434 | INFO | veMQ Broker: amq | TransportServerThreadSupport | ort.TransportServerThreadSupport 72 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Listening for connections at: tcp://host1:61616
2013-11-05 12:26:32,435 | INFO | veMQ Broker: amq | TransportConnector | tivemq.broker.TransportConnector 254 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Connector openwire Started
2013-11-05 12:26:32,437 | INFO | veMQ Broker: amq | BrokerService | he.activemq.broker.BrokerService 658 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Apache ActiveMQ 5.8.0.redhat-60024 (broker_host1, ID:host1-60970-1383672392281-0:1) started
2013-11-05 12:26:32,476 | INFO | veMQ Broker: amq | ActiveMQServiceFactory | q.fabric.ActiveMQServiceFactory$ 52 | 120 – org.jboss.amq.mq-fabric – 6.0.0.redhat-024 | Broker amq has started.
2013-11-05 12:35:59,091 | INFO | qtp252820188-194 | RemoteJMXBrokerFacade | tivemq.web.RemoteJMXBrokerFacade 153 | 133 – org.jboss.amq.mq-web-console – 5.8.0.redhat-60024 | Connected via JMX to the broker at service:jmx:rmi:///jndi/rmi://host1:1091/karaf-root

Start do host2

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

./amq 

Console host2

2013-11-05 12:26:37,533 | INFO | veMQ Broker: amq | PListStoreImpl | tore.kahadb.plist.PListStoreImpl 331 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | PListStore:[/opt/jboss-a-mq-6.0.0.redhat-024/data/amq/broker_host2/tmp_storage] started
2013-11-05 12:26:37,588 | INFO | Executor: 1 | DispatcherServlet | ork.web.servlet.FrameworkServlet 463 | 133 – org.jboss.amq.mq-web-console – 5.8.0.redhat-60024 | FrameworkServlet ‘dispatcher’: initialization completed in 338 ms
2013-11-05 12:26:37,657 | INFO | JMX connector | ManagementContext | q.broker.jmx.ManagementContext$1 138 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1092/jmxrmi
2013-11-05 12:26:37,667 | INFO | veMQ Broker: amq | BrokerService | he.activemq.broker.BrokerService 595 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Using Persistence Adapter: KahaDBPersistenceAdapter[/shared]
2013-11-05 12:26:37,778 | INFO | veMQ Broker: amq | SharedFileLocker | .activemq.store.SharedFileLocker 58 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Database /shared/lock is locked… waiting 10 seconds for the database to be unlocked. Reason: java.io.IOException: File ‘/shared/lock’ could not be locked.
2013-11-05 12:26:47,899 | INFO | veMQ Broker: amq | SharedFileLocker | .activemq.store.SharedFileLocker 58 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Database /shared/lock is locked… waiting 10 seconds for the database to be unlocked. Reason: java.io.IOException: File ‘/shared/lock’ could not be locked.
2013-11-05 12:26:58,012 | INFO | veMQ Broker: amq | SharedFileLocker | .activemq.store.SharedFileLocker 58 | 104 – org.apache.activemq.activemq-osgi – 5.8.0.redhat-60024 | Database /shared/lock is locked… waiting 10 seconds for the database to be unlocked. Reason: java.io.IOException: File ‘/shared/lock’ could not be locked.

Ou seja: aguardando a liberação do lock, tentando checar a cada 10 segundos

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,tcp://maquina2: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.

fuse-amq

Vou deixar enviando até completar 10 mensagens e em seguida derrubarei o broker que está recebendo as mensagens:

[ActiveMQ Task-1] FailoverTransport INFO Successfully connected to tcp://host1:61616
Sent message 0
Sent message 1
Sent message 2
Sent message 3
Sent message 4
Sent message 5
Sent message 6
Sent message 7
Sent message 8
Sent message 9
Sent message 10
[na/192.168.122.153:61616@52382] FailoverTransport WARN Transport (tcp://192.168.122.153:61616) failed, reason: java.io.EOFException, attempting to automatically reconnect
[ActiveMQ Task-1] FailoverTransport INFO Successfully reconnected to tcp://host2:61616
Sent message 11
Sent message 12
Sent message 13
Sent message 14
Sent message 15
Sent message 16
Sent message 17
Sent message 18
Sent message 19
Sent message 20

Acessando o console

http://host2:8181/activemqweb/queueGraph.jsp

queue-view


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!