Melhores práticas de performance para aplicações web – python, asp.net, java, etc

Falar em performance para aplicações web é algo muito complexo. Envolve diretamente uma série de variáveis, desde configurações de máquina (hardware), configuração do seu modelo de rede, até o desenvolvimento e tunning da sua aplicação. Vale ressaltar que uma aplicação performática é resultado de uma equação de tunning de software e hardware, e ao contrário que muitos desenvolvedores imaginam, uma aplicação bem desenvolvida requer muito menos recursos de infra-estrutura.

Alguns dos pontos listados aqui são resultados de longos anos de experiência, de pesquisa e de práticas que diversas equipes com que venho trabalhando aplicam. Além disso, vale a pena olhar iniciativas como YSlow (Yahoo) e PageSpeed (Google), ambas lideradas por um cara chamado Steve Souders, referência no assunto.

Para começar, imagine-se num cenário onde seu negócio depende exclusivamente de resultados de aplicações web, e que todos os esforços devem ser aplicados para que seu site esteja altamente disponível, com o menor custo possível. Quais seriam os pontos que você atacaria para que tenha sucesso na sua empreitada ?

Que tal começar por esses abaixo ?

  • Verificar toda a configuração de hardware do seu parque de máquinas;
  • Realizar testes de estresse e chegar em um modelo que determine o volume máximo de transações que sua aplicação aguenta;
  • Realizar um benchmark com outros aplicativos que tenham as mesmas características e determinar planos de ação;
  • Aplicar um guia de boas práticas – que estão descritas mais pra frente
  • Traçar um plano de melhoria para suas aplicações;

Guia de boas práticas para sua aplicação:

Carregue somente o necessário na página:

Lembre-se que mesmo que não estejam em uso, os recursos são carregados se tiverem referências no HTML. Javascripts são os vilões para liberar a renderização da página, por parte do browser.

Otimize os recursos:

Otimize imagens, javascripts, css. Técnicas como css sprites, “minificação” de javascripts e redução de paleta de cores são as mais utilizadas e diminuirão o uso de recursos de rede de forma drástica.

Lembre-se do item número um – os javascripts seguram a renderização da página até que sejam totalmente baixados. Existem técnicas que amenizam isso, e uma das mais utilizadas é manter os arquivos de javascript no final da página, antes da tag body.

Para os arquivos css, coloque-os na tag head da página, diferentemente do que foi feito com os Javascript. O time do YSlow descobriu, através de experimentos, que tal ação faz a página renderizar de forma mais rápida.

Diminua o acesso ao banco de dados, faça cache:

Cache é uma das técnicas mais aplicadas nas aplicações web. O número de opções é bem grande: Pode ser cache em disco, cache distribuído, cache em memória etc…

Acessos ao banco de dados podem ser considerados um dos recursos mais caros pela aplicação web. Apesar de existirem técnicas de pooling de conexões para redução do tempo de latência entre a conexão do servidor web com o banco de dados, mecanismos de SELECT, INSERT, UPDATE e DELETE podem ser muito complexos e causarem altíssimos atrasos nas respostas.

Imagine uma página que faz 10 requisições ao banco a cada atualização de página, sendo que seu conteúdo que muda somente cinco ou seis vezes por dia. O custo de requisições frequentes ao banco de dados é alto, portanto, vale a pena realizar um cache dessa página (guardando somente o html resultante em disco).

Vale a pena tentar reduzir o número de chamadas, ou tentar guardar em algum mecanismo de cache dados que sejam frequentemente chamados pela aplicação e que não são alterados com tanta frequência. Como exemplo, podemos imaginar uma lista de estados ou cidade.

Realize flush da página assim que possível:

Pode parecer excesso de zelo, mas não é! Praticamente todas as linguagens de programação implementam um mecanismo de buferização do html, antes de começar a liberar os dados. Algumas até esperam que todo o conteúdo da página seja processado, para liberar o HTML ao browser.

No asp.net , você pode user o Response.Flush , no PHP você pode usar a função flush(); e assim por diante …

Mova conteúdo estático para outros domínios:

Essa técnica serve para reduzir o envio desnecessário de cookies, além de possibilitar uma migração futura para um CDN (content delivery network). Misturar aplicações dinâmicas com conteúdo dinâmico pode gerar um overhead desnecessário para o servidor web, principalmente no que se diz respeito a cookies. Os cookies são salvos no browser e a cada request realizado, são retransmitidos ao servidor web, até que os mesmos expirem.

Para uma página dinâmica, como um aspx, php, faz todo sentido receber os cookies de volta, caso tenham sido gravados, ou até mesmo usados para implementação de session. Mas não faz sentido retransmití-lo ao chamar arquivos como imagens, css, etc.

Além disso, tal prática vai possibilitar que você sirva conteúdo através de CDN´s em um segundo momento, sem muita dor de cabeça. CDN´s são utilizados em larga escala por empresas grandes – como exemplo cito o Google e o Facebook. Esses mecanismos implementam um sistema distribuído de cacheamento e roteamento, servindo os dados de um servidor mais próximo ao usuário, com menor latência de rede.

Utilize ferramentas para análise de desempenho – conhecidas por profilers:

Em java é muito comum usar ferramentas para análise de código fonte, que identificam possíveis problemas de performance ou overhead.

Guia de boas práticas para infra-estrutura:

Apesar de muitas das práticas estarem baseadas no servidor Apache, com certeza você você poderá aproveitá-las para outros servidores web como IIS, por exemplo.

Faça uso de balanceadores de carga:

Balanceadores de carga representam uma forma fácil de aumentar os recursos de infra-estrutura. São feitos via hardware específico ou via software e os que mais utilizei são: Alteon, LVS ( linux ) e F5 BigIP.

O uso correto de tais aplicações melhoram e muito o desempenho, porém, vale lembrar que alguns pontos devem ser levados em consideração:

  • O uso de sticky session ( para aplicações autenticadas), diminui a capacidade de saída, uma vez que os mecanismos de balanceamento levam em consideração endereço ip do usuário;
  • Divida as configurações de domínio entre dinâmico e estático para garantir maior eficiência no balanceamento;
  • Evite balancear somente via DNS;

Ative a compressão de páginas:

Quando você vai transferir um arquivo grande você costuma zipá-lo, certo ? Para as páginas web você deveria fazer o mesmo. Browsers modernos como Firefox, Chrome e IE a partir da versão 8 suportam compressão, enviando um parâmetro no cabeçalho da requisição, para o servidor web.

Para os browsers que não suportam, o servidor web não vão comprimir os dados, portanto, não há efeitos colaterais para seu aplicativo. Essa técnica, apesar de aumentar um pouco o processamento, reduz drasticamente o tamanho dos arquivos, principalmente javascript, css e html´s.

Marque a data de expiração dos arquivos:

Arquivos como imagens dificilmente são modificados, portanto, marcar a data de expiração para uma data futura pelo servidor web, vai fazer com que o browser do usuário faça cache dos arquivos, não precisando enviar uma requisição novamente desse arquivo.

Compilação do servidor Apache:

Compile seu servidor para carregar somente os módulos que você precisa. Instalações padrão costumam vir carregadas de módulos opcionais que provavelmente você não vá usar e que estão lá ocupando memória de bobeira.

Além da compilação, escolha o melhor formato do Apache MPM (multi processing module). Existem dois formatos:

  • Worker MPM – que usa múltiplos processos filhos e threads para servir cada requisição. Tem um uso relativamente baixo de memória, porém seu nível de isolamento é menor. Se um processo filho é corrompido,  todas as threads pertencentes ao filho são afetadas. É melhor usado para máquinas com vários processadores;
  • Prefork MPM – usa multiplos processos filhos, porém, cada um deles é responsável por uma requisição http. É mais tolerante a falhas, pois cada processo filho é isolado. Porém esse nível de isolamento custa um maior uso de memória e quanto mais acesso, mais memória usada.

Utilize endereços IP ao invés de nomes nos arquivos de configuração:

Faça uso de endereços de IP, para prevenir chamadas desnecessárias de DNS. Normalmente essas entradas são usadas em diretivas Allow e Deny no Apache.

Não use AllowOverride None:

Essa diretiva no Apache gera chamadas desnecessárias no filesystem. Basicamente, para cada diretório/subdiretório de um determinado arquivo, o Apache fará chamadas para localizar arquivos .htaccess .

Configure o KeepAlive e o KeepAliveTimeout:

Para páginas com muitas imagens, uma única conexão TCP pode ser usada para trazer os dados, reduzindo latência de rede.

Divida o conteúdo dinâmico do estático em dois servidores:

Usando o mod_proxy você pode fazer com que um servidor tipo lighthttp ou apache sem nenhum módulo ativo, possa servir conteúdo estático e repassar para um Apache o conteúdo dinâmico.

Pelo fato dos segmentos de memória usados pelo servidor web não serem divididos e realocados até que os processos acabem (ou deixei de existir), o uso de conteúdo dinâmico mesclado com conteúdo estático pode gerar overheads desnecessários. Exemplo: uma página PHP pode carregar 20MB de memória ram, e após liberado, esse espaço de memória não será desalocado e pode dar espaço para servir um arquivo jpeg que não usará todo esse espaço de memória.

Evite o uso de CGI – use módulos para melhorar performance:

Módulos como FastCgi, mod_php, mod_perl, mod_python, melhoram e muito a performance dos aplicativos dinâmicos. Ao invés de configurá-los como CGI diferetamente, dê preferência ao uso desses módulos citados.

Adquira um CDN, caso possível:

Se grande parte de seu conteúdo é composto por arquivos de mídia – imagens, vídeos, áudio, etc, considere a hipótese de usar um CDN – content delivery network. Além de reduzirem a carga de rede da sua infra-estrutura, aumentam e muito a velocidade em que o conteúdo é servido, pois seus mecanismos de cache procuram um servidor que terá a menor latência para servir ao usuário final.

Ex: Se um usuário que está nos EUA solicitar o download de um vídeo, o CDN vai rotear o usuário para um servidor dos EUA, que terá uma latência muito menor do que vir até um servidor localizado no Brasil. Há um custo de roteamento alto nessa transação.

Utilizei duas soluções com muito sucesso em diversos aplicativos:

  • Akamai Edge Server – solução oferecida pela Exceda, no Brasil;
  • MaxCDN – Possui um custo barato, porém, ainda não existe cobertura de servidores no Brasil;

Acho que é isso. Tentei cobrir, na medida do possível, alguns pontos de forma genérica. Tentarei manter esse guia sempre atualizado, e é claro, sua opinião é fundamental. Se tiver algo para contribuir, deixe um comentário.

Não deixe de instalar as ferramentas YSlow e PageSpeed no seu Firefox. Dão dicas valiosas para aumentar o desempenho do seu aplicativo.

Um abraço,

Robson Dantas

Bookmarksbookmark bookmark bookmark bookmark bookmark bookmark

Popularity: 3%

No Comment

Vale Presente