Sem reinventar a roda, cache de páginas com EhCache e ServletFilter
Não faz muito tempo, surgiu a necessidade de aumentar o desempenho de uma aplicação JEE, e começamos a ver profile daqui, examina relatórios dali, nisso um amigo de projeto, que a pouco tempo havia se enturmado com Rails, teve uma idéia: "Por que não fazemos cache das páginas mais frequentes, podemos criar um pequeno framework, e fazer como o Rails faz", explicando... em Rails basta colocar no controller as páginas que você deseja que sejam "cacheadas". Ex:
-
caches_page :noticias
Pronto, a primeira chamada à action "noticias" cria o cache, e será usada pelas chamadas subsequentes. Para expirar o cache basta chamar:
-
expire_page(:controller => 'public', :action => 'noticias')
Mais detalhes e excelente tutorial no Rails Envy.
Eu gosto muito de criar coisas novas, mas como dito no último post, criar mais um mini-framework para dar manutenção em uma aplicação já não muito pequena... bem, não obrigado. Foi por isso que eu disse: "Cara, dá uma pesquisada, com certeza alguém já fez isso." E pra variar, sim alguém já fez isso.
O excelente e bem conhecido EhCache possui esta funcionalidade e muitas outras.
Este mini tutorial parte do pressuposto que já se tem conhecimento do EhCache e de ServletFilter, para quem não conhece qualquer um dos dois, sem pânico, são muito fáceis de serem utilizados, vale uma pesquisada por tutoriais.
Para facilitar a vida, podem baixar este anexo com a aplicação-exemplo que fiz, basta colocá-lo em seu container web predileto, no meu caso testei no Tomcat, e acessar as URLs de teste:
http://localhost:8080/cache/semcache/teste.jsp
http://localhost:8080/cache/comcache/teste.jsp
O exemplo, mostra a hora atual em milesegundos. A página com cache, após acessada, terá 10 seg de vida.
Para implementar bastou os seguintes passos:
- Baixar e instalar os jars EhCache (ehcache-1.3.0-beta.jar), EhCache Constructors (ehcache-constructs-0.7.3.jar) e Commons-logging (dependência requerida) no diretório lib.
- Incluir no arquivo ehcache.xml as configurações para cache de página, as propriedades falam por si, configurem a gosto:
-
<cache name="SimplePageCachingFilter"
-
maxElementsInMemory="10000"
-
maxElementsOnDisk="1000"
-
eternal="false"
-
overflowToDisk="true"
-
timeToIdleSeconds="10"
-
timeToLiveSeconds="10"
-
memoryStoreEvictionPolicy="LRU"
-
>
- Configurar um ServletFilter no web.xml, para a implementação de filtro SimplePageCachingFilter
-
<filter>
-
<filter-name>SimplePageCachingFilter</filter-name>
-
<filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
-
<init-param>
-
<param-name>suppressStackTraces</param-name>
-
<param-value>false</param-value>
-
<description>Whether to suppress stack traces in the filter</description>
-
</init-param>
-
</filter>
- Indicar para quais páginas fazer cache a partir do ServletFilter definido acima, dentro do web.xml. No exemplo, tudo que estiver abaixo do diretório "comcache".
-
<filter-mapping>
-
<filter-name>SimplePageCachingFilter</filter-name>
-
<url-pattern>/comcache/*</url-pattern>
-
</filter-mapping>
Pronto, é somente isso, a página será devidamente cacheada, seguindo as configurações do ehcache.xml.
Caso queira fazer cache de apenas uma parte da página, no caso de quem utiliza jsp:include, basta utilizar a outra implementação PageFragmentCachingFilter
Essa pequena implementação já garantiu um bom desempenho em várias páginas e sem reinventar a roda criando um mini-framework para esta função.
Se alguém souber de outro meio para fazer cache de página em Java, por favor esteja a vontade para comentar, gostaria muito de conhecer outras implementações.