A técnica de caching é amplamente conhecida e utilizada pelos desenvolvedores de software para aumentar a performancedos sistemas. O seu funcionamento consiste em manter as informações mais frequentemente acessadas na memória, evitando assim repetir todo o processo utilizado para obter esta informação (o que pode incluir diversas consultas ao banco de dados).
No contexto de um site ou aplicativo web, a vantagem do caching está na reutilização do HTML final gerado pelo processamento feito no servidor. Esta reutilização permite que os recursos físicos do servidor sejam economizados, o que permite que um número maior de acessos possa ser disponibilizado por ele.
Para entendermos melhor as vantagens do caching no ASP.NET, precisamos antes de mais nada, compreender o papel de cada uma das partes envolvidas no funcionamento de um site dinâmico ou aplicativo web e identificar os pontos que podem causar gargalos na sua utilização.
Todo site dinâmico precisa de pelo menos dois elementos para funcionar corretamente: um servidor web e um servidor de banco de dados. No caso da framework .NET, o servidor web é o IIS (Internet Information Server) presente em todas as versões para servidor do Windows. Já o banco de dados escolhido vai depender exclusivamente da escolha do desenvolvedor. Normalmente utiliza-se o SQL Server, devido às inúmeras ferramentas que facilitam o desenvolvimento, mas nada impede que sejam utilizados o MySQL ou o Oracle, por exemplo.
O servidor web é aquele responsável por responder as requisições de acesso feitas pelos usuários, processar de acordo com a linguagem de programação utilizada no desenvolvimento e eventualmente obter informações de um banco de dados.
Vamos imaginar por um instante um site de um pequeno jornal do interior, com poucos acessos diários, onde na sua home page é possível encontrar uma seção de últimas notícias, com informações atualizadas frequentemente e obtidas de um banco de dados.
A cada acesso feito a este site, o servidor web irá fazer uma requisição ao servidor de banco de dados solicitando uma lista das notícias mais recentes, processará essa informação gerando um código HTML e retornará esta informação para o usuário, que será exibida no seu navegador.
Num determinado dia este jornal divulga no seu site um grande furo jornalístico, fazendo com que repentinamente o número de acessos passe de um milhão. O processo de obtenção das informações do banco de dados, que antes era executado algumas dezenas de vezes por dia, repentinamente passa a ser executado um milhão de vezes num curto espaço de tempo.
Este aumento súbito causa uma pane no servidor de banco de dados, que não é capaz de atender o número de requisições na mesma velocidade em que elas são solicitadas. O usuário passa então a sentir uma repentina lentidão no carregamento das páginas, culminando na exibição de mensagem de erros ao tentar acessar o site e eventualmente deixando o site fora do ar.
Voltando a técnica de caching, como ela poderia ser utilizada para minimizar este problema e aumentar a performance do servidor, evitando que o site saia do ar?
Como mencionei no começo deste texto, o funcionamento do cache consiste em manter as informações mais frequentemente acessadas na memória, evitando assim repetir todo o processo utilizado para obter esta informação (o que pode incluir diversas consultas ao banco de dados).
No nosso exemplo do jornal, as informações frequentemente acessadas são justamente a lista de últimas notícias, e o processo de obtenção é todo o fluxo de requisição feito pelo servidor web para o servidor de banco de dados e o processamento destas informações.
Se mantivermos na memória do servidor web essa lista de últimas notícias já processada e pronta para ser exibida, estaremos desafogando o servidor de banco de dados, uma vez que será feita apenas uma requisição inicial e também economizando os ciclos do processador, que não precisará formatar a informação toda vez que ele for requisitada.
Quando bem configurado o cache permite que os servidores web sejam capazes de atender a milhares de requisições num curto espaço de tempo, aumentando a performance e a disponibilidade dos sites dinâmicos.
O ASP.NET oferece diversos tipos de caching que podem ser usados para otimizar a performance dos aplicativos web. Cada um deles tem uma utilização específica, e quando combinados permitem obter as mais flexíveis configurações, que se adaptam facilmente as suas necessidades.
Output Caching
O Output Caching é recomendado para os casos em que todo o conteúdo da página pode ser armazenado no cache. Em sites com muitos acessos, armazenar no cache as páginas mais acessadas, mesmo que por períodos curtos de tempo, pode representar um enorme ganho de performance.
Quando uma página é armazenada no OutputCache, todos os acessos subsequentes serão servidos diretamente pelo cache, sem executar o código que a gerou.
No nosso exemplo anterior, imaginemos que a página que contém a notícia do furo jornalístico foi linkada por um jornal famoso, atraindo um grande número de visitantes só para ela. Esta página específica é uma grande candidata a ser armazenada no OutputCache, uma vez que o seu conteúdo passou a ser o mais requisitado de todo o site.
Para armazenar uma página inteira no cache bata utilizar a diretiva OutputCahe na declaração da página, conforme o exemplo abaixo:
<%@ OutputCache Duration=”60″ VaryByParam=”none”%>
O atributo Duration determina o tempo, em segundos, que a página será armazenada no cache. Já o atributo VaryByParam indica que a página não muda de acordo com nenhum parâmetro GET ou POST.
O atributo VaryByParam permite que sejam adicionadas múltiplas páginas no cache, de acordo com um parâmetro da querystring, por exemplo. Supondo que tivéssemos um parâmetro chamado mes, que retornasse a lista de notícias de um terminado mês, poderíamos armazenar individualmente no cache usando a seguinte diretiva:
<%@ OutputCache Duration="60" VaryByParam="mes"%>
Fragment Caching
Além de permitir o armazenamento de toda a página no cache, o ASP.NET também oferece a possibilidade de armazenar apenas determinadas regiões de uma página. Estas regiões são determinadas através da utilização de um user control (*.ascx), onde você determina dentro dele a diretiva OutputCache demonstrada no item anterior.
Vamos imaginar a home page do nosso pequeno jornal, onde todo o conteúdo é estático e apenas o bloco de últimas noticias é sofre alterações constantes. Poderíamos então definir um cache bastante longo para a página, digamos de uma hora, e um mais curto de 5 minutos para as últimas notícias, uma vez que o seu intervalo de atualização é mais frequente.
Para isto basta criar um user control e colocar dentro dele toda a lógica de obtenção das últimas notícias. No arquivo ascx, definiríamos a diretiva conforme o exemplo abaixo:
<%@ OutputCache Duration=”300″ VaryByParam=”none”%>
E na página aspx que atende a home page, usaríamos a seguinte diretiva:
<%@ OutputCache Duration=”3600″ VaryByParam=”none”%>
Utilizando o fragment caching podemos customizar ao extremo a configuração do caching, permitindo ajustar os tempos de armazenamento de acordo com as particularidades do site em questão.
Data Caching
E finalizando a lista de opções de caching do ASP.NET temos o Data Caching, que permite armazenar na memória do servidor web qualquer tipo de informação desejada. Esta opção oferece uma interface de dicionário que permite a fácil inclusão e obtenção de informações do cache, oferecendo uma grande ferramenta para aumentar ainda mais a disponibilidade do site.
Mas que tipo de informação poderia ser armazenada no Data Caching? Vamos imaginar um site de venda de passagens aéreas, onde podemos encontrar dois menus drop down contendo a lista de destinos oferecidos para a empresa.
A lista de cidades atendidas por uma empresa aérea não sofre alterações frequentes, portanto ela é uma ótima candidata a ser armazenada em um cache. Mas como estamos falando de dados brutos, e não do resultado de processamento feito por um código no servidor, não podemos usar nem o OutputCache nem o FragmentCache para armazenar estas informações.
É justamente aí que entra o Data Caching. A engine utilizada pelo data caching é individual para cada aplicativo hospedado no servidor, armazena as informações diretamente na memória e a sua vida útil é equivalente ao tempo de vida útil do aplicativo. Quando o aplicativo é reiniciado o cache também é reiniciado.
No nosso exemplo, para evitar que a lista de cidades seja carregada do banco de dados toda vez que a página de reservas for acessada, podemos adicioná-la ao cache na primeira vez em que for solicitada, passando a acessar diretamente do cache nas requisições subsequentes. Isso tudo pode ser feito com quatro simples linhas de código:
myValue = Cache["mykey"];
if(myValue == null ) {
myValue = GetDataFromDB();
Cache["mykey"] = myValue;
}
Este bloco de código funciona da seguinte forma: primeiro obtemos a informação do cache e em seguida testamos se ela contem algum valor. Se ela for nula significa que é a primeira vez que esta informação está sendo requisitada, sendo necessário fazendo uma consulta ao banco de dados. Após obter essa informação do banco de dados basta colocá-la no cache, evitando assim futuras requisições ao banco de dados.
As ferramentas de caching oferecidas pelo ASP.NET são poderosas e flexíveis, permitindo a criação de sites dinâmicos e aplicativos web que aguentam tranquilamente aumentos repentinos na quantidade de requisições, tornando-os estáveis e confiáveis. Portanto, não perca mais tempo, passe a usar o caching para aumentar a disponibilidade do seu site.
Humberto Oliveira é um programador que também é designer, gosta tanto de internet que criou uma empresa de software especializada no desenvolvimento de aplicativos web e na criação de websites. Pode ser encontrado no site http://holiveira.com