terça-feira, 2 de fevereiro de 2010

Cache de páginas com o framework EhCache

Olá pessoal,

Há bastante tempo não escrevo nada. Resolvi falar agora sobre melhorias de performance que ajudam bastante a aplicação. Em sites, constantemente temos páginas que acessam várias consultas pesadas além de regras de negócio. Estas páginas quando muito acessadas causam freqüentemente problemas de desempenho na aplicação e páginas lentas.

Um dado importante para se tomar a decisão de utilizar ou não cache em páginas é a relação entre corretude e performance. Imagine o seguinte caso: Você tem uma página que possui as últimas notícias da sua empresa. Se uma nova notícia nova acaba de sair, qual o impacto da notícia demorar um pouco a mais para entrar no ar? O ganho de performance vale a pena o atraso na notícia. Se sim é interessante utilizar neste caso o cache para esta página.

Quando temos cenários parecidos com este podemos verificar se é possível realizar cache de páginas. O Ehcache que é um framework java possui além do cache de objetos e cache para acesso a dados com JPA, possui também cache de páginas. Este cache às vezes é mais interessante, porque uma mesma página pode possuir várias consultas e regras de negócio, o que faz com que o cache de página geralmente gere mais ganho de performance do que o cache de acesso a dados.

Para definir o cache de páginas é necessário primeiramente baixar os jars do ehcache disponíveis em http://ehcache.org. Entre os jars necessários é necessário baixar o módulo ehcache-web, que possui a Servlet responsável por gerenciar e guardar o cache das páginas.

Depois disto, no classPath (pode ser na pasta src por exemplo) deve ser adicionado o aquivo ehcache.xml com um conteúdo parecido com o abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir" />
<cache name="SimplePageCachingFilter" maxElementsInMemory="10"
eternal="false" timeToIdleSeconds="600"
timeToLiveSeconds="600" overflowToDisk="true" />

<defaultCache maxElementsInMemory="10" eternal="false"
overflowToDisk="false" timeToIdleSeconds="120"
timeToLiveSeconds="120" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" />
</ehcache>


Para o arquivo acima é necessário verificar o tempo de expiração do cache que é definido pela propriedade timeToLiveSeconds que representa o número de segundos do cache da página apresentada.

Depois, no arquivo web.xml devemos adicionar o filtro de cache para as páginas necessárias, assim como mostrado abaixo:

<!-- Filtros para cache de páginas adicionado para páginas -->
<filter>
<filter-name>SimplePageCachingFilter</filter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>SimplePageCachingFilter</filter-name>
<url-pattern>/index.jsf</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SimplePageCachingFilter</filter-name>
<url-pattern>/noticias.jsf</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SimplePageCachingFilter</filter-name>
<url-pattern>/rss.jsf</url-pattern>
</filter-mapping>


A melhoria de performance é bastante significante. Além do cache de páginas comum é possivel também compactar as páginas, adicionar cabeçalhos, entre outros. Para mais informações visitem http://ehcache.org/documentation/web_caching.html.

É isto aí pessoal. Qualquer problema avisem...

quarta-feira, 9 de setembro de 2009

Resultado da enquete sobre certificações Sun

Olá pessoal,

Chegamos ao resultado de mais uma enquete. Desta vez sobre certificações Sun. Segue abaixo o resultado:

resultado enquete

Pelas respostas dos visitantes do site vimos que a grande maioria (57%) ja possuem a certificação de Programador (SCJP). Logo atrás em segundo lugar, com 38% das respostas estão os visitantes que responderam que não possuem nenhuma certificação.

Em terceiro lugar com 32% estão os certificados em Desenvolvimento Web (SCWCD). Muito próximo, logo abaixo estão os visitanes com certificação Associate (SCJA) e em Componentes de Negócios (SJBCD) com respectivamente 18% e 16% das respostas.

12% dos visitantes que responderam a enquete possuem a certificação de arquiteto (SCEA) e 7% a de Web Services (SCDJWS). Por último ficaram as certificações de desenvolvedor (SCJD) e de desenvolvedor para aplicações móveis (SCMAD) empatados com aproximadamente 6% das respostas.

Nesta última votação tivemos uma participação ainda mais ativa dos visitantes. Em breve teremos novas enquetes e continuem votando.

É isto aí pessoal.

segunda-feira, 31 de agosto de 2009

Apache Native Library no Tomcat ou Jboss

Olá pessoal,

Trabalhando com melhoria de performance de aplicações a algum tempo verificamos algumas mudanças que podem ser aplicadas no servidor de aplicação e que surtem efeito na aplicação como um todo. Entre estas melhorias uma que é uma opção para aplicações que utilizam servidores como o Tomcat e o JBoss é a utilização do Apache Tomcat Native Library (APR).

O Apache Tomcat Native Library é um JNI (Java Native Interface) que provê grande parte das funcionalidades do Tomcat em código nativo ao invés de utilizar Bytecode Java. Isto na prática significa maior velocidade da aplicação, uma melhor escalabilidade e melhor integração com os serviços nativos da máquina. Por default o Tomcat não vem com o APR já compilado e aplicado a distribuição, pois isto tornaria o servidor dependente de plataforma, mas sua utilização é bastante recomendável em ambientes de produção.

Entre as vantagens de sua utilização temos acesso a funcionalidades avançadas de IO (SendFile, Epoll e OpenSSL), funcionalidades do sistema operacional (Geração aleatória de números, status do sistema, etc.) e acesso a processos nativos (Memória compartilhada, NT pipes e Sockets).

Quando o APR não está instalado vemos o seguinte log no servidor de aplicação:
The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path

Para instalá-lo utilize os passos descritos em http://tomcat.apache.org/tomcat-6.0-doc/apr.html ou em http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Tomcat+Native+Library.

Assim que ele estiver instalado vemos o seguinte trecho no log do Tomcat:
INFO: Loaded APR based Apache Tomcat Native library 1.1.16.

Realizar os testes para verificar o quanto melhorou no desempenho da aplicação é um processo um pouco complicado, pois algumas operações podem ser mais beneficiada que outras. Em algumas referências vimos um ganho de até 10% na performance da aplicação em geral, mas realmente é um teste difícil de ser realizado.

Em um teste bem curto que fiz verificamos as seguintes medições apenas do tempo de startup do servidor sem e com a API nativa tive os seguintes resultados:

Tempos sem lib native:
2125 ms
2155 ms
2113 ms

Tempos com lib native:
1913 ms
1984 ms
1985 ms

Vimos então um ganho que se aproxima de 10% apenas para o startup do servidor.

É isto aí pessoal. Espero que isto ajude quem necessita otimizar a performance das aplicações.

Quaisquer problemas avisem...

quarta-feira, 26 de agosto de 2009

Implementando página de erro com JSF

Algumas pessoas estão tendo dúvidas sobre como implementar uma página de erro com JSF, e resolvi então criar este post para explicar uma maneira de implementar.

Para se realizar o redirecionamento pode se utilizar o ActionListener do JSF. Segue abaixo um exemplo de implementação da classe deste ActionListener:


/**
* Classe responsável por tratar erros inesperados do sistema.
*
* @author Samuel Delfim
*
*/
public class ExceptionHandler extends ActionListenerImpl {

@Override
public void processAction(ActionEvent event) {
// Obtem o contexto JSF
FacesContext context = FacesContext.getCurrentInstance();

try {
// Executa o método da classe Pai
super.processAction(event);

} catch (Exception e) {

// Se ocorrer um erro inesperado, exibe a mensagem abaixo
context.addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_FATAL, e.getMessage(), null));


// Redireciona para a pagina com o mapeamento 'erro'
// no faces-config.
context.getApplication().getNavigationHandler().
handleNavigation(context, null, "erro");
}
}
}


Pode-se, por exemplo, na classe acima realizar tratamentos diferentes para cada tipo de exceção.

Para aplicar o Listener em uma aplicação jsf deve ser colocado o seguinte trecho dentro do arquivo faces-config.xml:


<application>
<!-- Aplicação do Listener -->
<action-listener>com.thinkworks.handler.exception.ExceptionHandler
</action-listener>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
<locale-config>
<default-locale>pt_BR</default-locale>
<supported-locale>pt_BR</supported-locale>
<supported-locale>es_AR</supported-locale>
</locale-config>
<message-bundle>com.bionexo.mensagens.Mensagens</message-bundle>
</application>


O trecho a ser copiado se refere à tag e deve ser aplicado ao view-handler específico. Neste caso, o ViewHandler utilizado é o do projeto facelets que está sendo utilizado no projeto em questão.

Também no arquivo faces-config.xml deve ser realizado o mapeamento da página de erro.
Segue abaixo um exemplo de mapeamento de página de erro:


<navigation-rule>
<navigation-case>
<from-outcome>erro</from-outcome>
<to-view-id>/pages/erro/paginaErro.xhtml</to-view-id>
</navigation-case>
</navigation-rule>


É isto aí pessoal. Espero ter ajudado...

quinta-feira, 25 de junho de 2009

Configurando o EhCache como cache provider JPA

Olá pessoal,

Hoje vou falar um pouco sobre o EhCache e em seguida mostrarei como configurar o ehcache como provider de cache para o JPA.

Algumas vezes precisamos criar caches para linhas de banco de dados mais acessadas. Entre os problemas para a criação de um sistema de cache temos o sincronismo, o gasto excessivo de memória, o tamanho máximo do cache, entre outros. Devido à grande quantidade de possíveis problemas, escrever um sistema de cache eficiente, seguro e com suporte a sistemas distribuídos é um grande trabalho.

Este é o trabalho do cache de segundo nível do Hibernate (Second level Cache). É possível utilizar este cache com vários providers e um dos mais utilizados é o EhCache. O EhCache é um mecanismo de cache distribuído em Java vastamente utilizado. Ente seus principais recursos temos cache de entidades, de queries, de páginas web, entre outros.

Sua ultima versão está disponível em http://ehcache.sourceforge.net/.

Para configurá-lo como provider de persistência devemos primeiramente adicionar o seguinte trecho ao arquivo persistence.xml:


<property name="cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.provider_class"
value="net.sf.ehcache.hibernate.EhCacheProvider" />
<property name="net.sf.ehcache.configurationResourceName"
value="/META-INF/ehcache.xml" />

Depois devemos criar o arquivo ehcache.xml dentro do diretório META-INF da sua aplicação e adicionar nele o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="180"
overflowToDisk="true" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
</ehcache>


Um exemplo mais completo de arquivo de configuração do ehcache pode ser encontrado em http://ehcache.sourceforge.net/ehcache.xml.

Lembrem-se de adicionar o arquivo ehcache.jar dentro das bibliotecas de sua aplicação.

Depois de configurado então deverá aparecer no log do servidor algo como:


23:16:50,437 INFO [SettingsFactory] Second-level cache:
enabled
23:16:50,437 INFO [SettingsFactory] Query cache: disabled
23:16:50,437 INFO [SettingsFactory] Cache provider:
net.sf.ehcache.hibernate.EhCacheProvider


Depois disto é só começar a utilizar as anotações e o cachê de queries.

Em um próximo post falarei sobre como utilizar o cache de segundo nível com o Hibernate.