Uma situação muito comum para quem desenvolve aplicações que executam em um container java, como Glassfish ou Tomcat, é a necessidade de "mascarar" a porta do container atrás de um servidor web tradicional. Vou tentar explicar melhor.
Normalmente, subimos nosso container em uma porta diferente da 80, que é a porta web padrão, como por exemplo na porta 8080. Então para o usuário acessar nossa aplicação, ele precisa conectar em http://www.minhaempresa.com.br:8080/MinhaAplicacaoJava. Isso pode gerar alguns problemas, como o usuário não fixar a url do sistema, ou se confundir na hora da digitação, além de se tornar menos profissional, ao meu ver.
O objetivo proposto no artigo, é poder acessar a aplicação no seguinte endereço:
http://www.minhaempresa.com.br/MinhaAplicacaoJava. Sendo que teremos um servidor web apache rodando na porta 80 e um servidor java Glassfish rodando na porta 8080.
Depois de pesquisar um pouco, percebi que a maneira mais simples e transparente para atingir o objetivo, era instalar um módulo no servidor apache para tal funcionalidade. O nome do módulo é mod_jk.
Vamos a instalação
Ambiente ondo foi implementado:
- Glassfish 3.1.2.2 (build 5).
- CentOS Linux release 6.0 (Final)
- Java 7 build 1.7.0_01-b08
- Apache 2.2.15
- Tomcat Connectors 1.2.37
A única dependência que tive que instalar no linux foram gcc-c++ e httpd-devel, pois deu problema na compilação do conector. Caso você tenha o mesmo problema, aqui mostro como instalar no Centos:
$ yum install gcc gcc-c++ autoconf automake $ yum -y install httpd-develUbuntu
$ sudo apt-get install libapache2-mod-jk
Para fazer o processo no ubuntu, você pode acessar: http://recklessdeveloper.blogspot.com.br/2011/06/apache-e-glassfish-301-com-modjk-no.html
O conector você pode baixar em: http://tomcat.apache.org/connectors-doc/. Como eu baixei o source, então tive que compilar. A complilação é bem simples. Você deve descompactar os fontes do mod_jk, entrar na pasta e executar os seguintes comandos:
cd native/ $ ./configure --with-apxs=/usr/sbin/apxs $ make $ make install
Após a compilação e instalação, você deve criar o arquivo de configuração. No meu caso, ele foi criado em:
$ /etc/httpd/conf/workers.properties
Esse arquivo deve ter o seguinte conteúdo:
worker.list=worker1 worker.worker1.type=ajp13 worker.worker1.host=localhost worker.worker1.port=8009
Observação: Essa porta não precisa estar liberada externamente caso os dois servidors estejam rodando na mesma maquina.
Agora devemos configurar o httpd.conf:
LoadModule jk_module modules/mod_jk.so JkWorkersFile conf/workers.properties JkLogFile /var/log/mod_jk.log JkLogLevel debug JkLogStampFormat "[%a %b %d %H:%M:%S %Y]" JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories JkRequestLogFormat "%w %V %T" JKMount /MinhaAplicacaoJava/* worker1
Em JkWorkersFile configuramos o arquivo criado anteriormente. Em JKMount configuramos o contexto da nossa aplicação no Glassfish. Você pode adicionar varios pontos de montagem, um para cada aplicação.
Agora precisamos avisar o Glassfish que ele vai ouvir as requisições desse cara. Entre na pasta bin do Glassfish e execute os seguintes comandos:
$ ./asadmin create-http-listener --listenerport 8009 --listeneraddress 0.0.0.0 --defaultvs server jk-connector $ ./asadmin set configs.config.server-config.network-config.network-listeners.network-listener.jk-connector.jk-enabled=true $ .asadmin create-jvm-options -Dcom.sun.enterprise.web.connector.enableJK.propertyFile=domain-dir=/etc/httpd/conf/workers.properties
E pronto. Agora reinicie o Apache e o Glassfish e pode testar. Caso não funcione, verifique o arquivo de logs gerado em /var/log/mod_jk.log.
Até a próxima! vlw
Ricardo: tudo bem. Ao compilar .. este foi a saida
ResponderExcluirMaking all in common
make[1]: Entrando no diretório `/tmp/tomcat-connectors-1.2.37-src/native/common'
make[1]: Nada a ser feito para `all'.
make[1]: Saindo do diretório `/tmp/tomcat-connectors-1.2.37-src/native/common'
Making all in apache-2.0
make[1]: Entrando no diretório `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0'
make[1]: Nada a ser feito para `all'.
make[1]: Saindo do diretório `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0'
------------------------------------------
aqui o make install
make[1]: Saindo do diretório `/tmp/tomcat-connectors-1.2.37-src/native/apache-2.0'
make[1]: Entrando no diretório `/tmp/tomcat-connectors-1.2.37-src/native'
make[2]: Entrando no diretório `/tmp/tomcat-connectors-1.2.37-src/native'
make[2]: Nada a ser feito para `install-exec-am'.
make[2]: Nada a ser feito para `install-data-am'.
make[2]: Saindo do diretório `/tmp/tomcat-connectors-1.2.37-src/native'
make[1]: Saindo do diretório `/tmp/tomcat-connectors-1.2.37-src/native'
===========================================
Aqui quando tento habilitar
asadmin set -p 8484 configs.config.server-config.network-config.network-listeners.network-listener.jk-connector.jk-enabled=true
saida --->
No object matches the specified name "configs.config.server-config.network-config.network-listeners.network-listener.jk-connector.jk-enabled"
Olá Jonas,
ExcluirQue sistema operacional você está usando? O comando para criar o listener executou sem problemas? Parece que o jk-connector não foi criado. Faça o seguinte:
Entre no console do glassfish (asadmin) e execute o comando list-protocols, e veja se o jk-connector é listado.
ResponderExcluir
Olá Ricardo, excelente tutorial, parabéns.
ExcluirGostaria de saber se existe a possibilidade de colocar o sistema rodando diretamente no domínio, por exemplo, quando acesso "meusite.com.br", ele chamar a minha aplicação "meusite.com.br:8080/MinhaAplicacaoJava".
Obrigado desde já.
Olá Rafael,
ExcluirSim, você pode fazer isso. Eu conheço duas formas. Uma delas é você usar virtual hosting, onde você mapeia a requisição de um determinado domínio para uma aplicação. Você pode dar uma olhada aqui:
http://thierrywasyl.wordpress.com/2009/06/27/virtual-hosting-on-glassfish/
Nesse caso você pode ter vários hosts em um glassfish.
Outra maneira mais simples, é fazer o deploy da aplicação e colocar / no context root.
http://hobione.wordpress.com/2008/01/15/glassfish-docroot-for-%E2%80%9Croot%E2%80%9D-application-in-the-server-so-url-would-be/
Depois você colocaria o glassfish rodando na porta 80, ou faria o mapeamento com o mod_jk.
Legal Ricardo, estou com um pequeno problema antes disso, segui a configuração de acordo com o seu tutorial, mas quando faço uma requisição para o domínio configurado, ele dispara as seguintes linhas de erro no arquivo de log "mod_jk.log":
Excluir[Tue Nov 27 18:24:47 2012] [2140:2936] [debug] map_uri_to_worker_ext::jk_uri_worker_map.c (1131): Attempting to map URI '/index.php' from 1 maps
[Tue Nov 27 18:24:47 2012] [2140:2936] [debug] find_match::jk_uri_worker_map.c (945): Attempting to map context URI '/myapp/*=worker1' source 'JkMount'
[Tue Nov 27 18:24:47 2012] [2140:2936] [debug] jk_map_to_storage::mod_jk.c (3798): no match for /index.php found
Eu não entendi o porque da busca de index.php.
Agradeço desde já a ajuda.
O seu apache está configurado funcionando corretamente? Pelo que sei, o mod_jtk intercepta as requisições e verifica se deve fazer alguma coisa, caso não precise fazer nada, elas são devolvidas para o apache.
ExcluirEntão Ricardo, alguns minutos atrás consegui resolver o problema.
ExcluirEu estava utilizando um Virtual Host para tratar a requisição, como no exemplo abaixo:
VirtualHost *:80
ServerName localhost
JkMount /* worker1
/VirtualHost
O problema é que, como configuração geral do apache, ele tentava utilizar o mod_jk para todos esses tipos de arquivos quando uma requisição era feita:
DirectoryIndex index.php index.php3 index.html index.htm
Por isso na mensagem de erro, dizia que ele não havia conseguido encontrar o /index.php.
Resolvi esse problema, acrescentando a seguinte linha no meu Virtual Host:
VirtualHost *:80>
ServerName localhost
DirectoryIndex index.html index.htm
JkMount /* worker1
/VirtualHost
Assim ele tenta acessar apenas o arquivo index.html que eu preciso.