Desenvolvimento

Ξ 1 comentário

Performance utilizando Django: durma tranquilo

publicado por Victor Pantoja

Quem nunca sentiu um certo receio no momento do release de um novo site? Será que a performance será a esperada? Ou ainda: o site atual simplesmente resolveu dar um problema no meio da madrugada… as luzes piscam por todo o lugar na sala de operação. Se o seu sistema foi incrivelmente bem projetado, feito sem pressão de entrega, possui logs muito bem organizados e está bem documentado a ponto da operação resolver tudo sozinha, bom pra você! Mas sabemos que não é assim e, provavelmente, você que está lendo este artigo já foi acordado no meio da madrugada.

Existem diversas formas de se prevenir (recomendo muito a leitura do excelente Release It!) mas não existe um passo a passo para a criação de um site que possua uma boa performance e que seja estável 100% do tempo. Tenho alguns anos de experiência no desenvolvimento do globoesporte.com, sportv.com e do Cartola FC e acredito que este artigo possa ajudar outros desenvolvedores.

Apenas para contextualizar, o globoesporte.com é o maior portal de esportes de toda a América Latina. Recebemos cerca de 20 milhões de visitantes únicos por mês e diversos foram os desafios ao longo dos anos. Não é segredo que nós utilizamos Python / Django e acredito que muitos já tenham lido que Django não escala (ou ainda: que o próprio Python não escala). Porém, acredito fortemente que a performance vem da arquitetura da sua aplicação e não da linguagem propriamente dita.

Performance

Basicamente, nossos gargalos são três, não necessariamente nesta ordem de criticidade. O primeiro deles, é o MySQL, devido ao uso intensivo de requisições ao sistema. Deve-se tomar muito cuidado ao desenhar sua aplicação utilizando o Django pois ele pode fazer diversas sub requisições sem que você saiba. O segundo, é o Virtuoso (um banco de triplas), devido a demora de resposta. Por último, temos bastante I/O devido a consultas intensiva a APIs

Para reduzir esses gargalos, demos três passos, a saber.

Caching

O primeiro passo foi a utilização de um mecanismo de caching. Nós desenvolvemos uma estratégia de uso cache para lidar com nossas necessidades de desempenho e reduzir o espaço de memória utilizada (a solução é detalhada no artigo Uso otimizado de cache para performance de aplicações WEB). Use cache sempre que possível! Quando não for possível, reveja sua arquitetura!

Pré-Geração de Conteúdo

O segundo passo foi impedir que requisições do usuário iniciassem processos críticos. Algumas das páginas do globoesporte.com possuem integração com diversas APIs internas e externas e, por mais enxuto e otimizado que nosso código seja, depender de processamento externo é sempre um risco. Assim, sempre que possível, utilizamos um mecanismo de pré-geração de conteúdo, disparado por um evento de publicação editorial. Atualmente, utilizamos o staticgenerator (https://github.com/timetric/django-staticgenerator) para gerar o conteúdo estático de nossas homes e matérias.

Server Side Include (SSI)

O terceiro passo, dado relativamente a pouco tempo, consistiu em dividir nossas páginas em blocos com ciclos de cache diferentes. Na prática, isso significou eliminar chamadas Ajax e trocá-las por blocos de HTML incluídos pelo servidor WEB (SSI). A home do Flamengo, por exemplo, possui um componente de classificação que é atualizado a cada 10 minutos e um componente de “últimas notícias” atualizado a cada 2 minutos. Ambos são incluídos na página através de SSI. Essa técnica, inclusive, melhora a performance client-side ao reduzir a quantidade de javascript executado pelo navegador.

Performance Client-Side

E, por falar em performance client-side, deve-se prestar atenção à quantidade de arquivos estáticos (CSS, JS e imagens) que sua página terá e que implicarão em requests (e processamento) ao servidor web. Algumas técnicas simples reduzem a quantidade de requests:

  • minify de CSS e JS: utilize uma ferramenta avança, como o compass, para atingir esse objetivo;
  • caching do browser: seu navegador é experto o suficiente para guardar arquivos com o mesmo nome no cache. Assim, procure criar blocos de CSS e JS comuns às páginas. O globoesporte.com possui centenas de páginas de times. Além do conteúdo, a única diferença entre elas é a cor específica de cada time. Dessa forma, temos um grande bloco de CSS que se repete e é cacheado pelo browser;
  • junte as imagens em arquivos chamados “sprite”. Desenvolvemos o nosso próprio gerador dinâmico de sprites, o Spriter;
  • configure um tempo de expiração adequado para seus estáticos;
  • ative o gzip no seu servidor web. Os navegadores modernos suportam essa compressão.
  • sirva os arquivos estáticos em uma farm separada;

É importante que seu servidor esteja configurado corretamente. Abaixo, um exemplo de resposta do servidor do globoesporte.com:

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 16 Jan 2014 23:54:40 GMT
Content-Type: text/html; charset=utf-8
Accept-Encoding:gzip,deflate,sdch
Connection: close
Last-Modified: Thu, 16 Jan 2014 23:52:33 GMT
Expires: Thu, 16 Jan 2014 23:57:33 GMT
Cache-Control: max-age=30

Após aplicar as técnicas descritas aqui no artigo, não esqueça de monitorar a performance da sua aplicação! Destaco três ferramentas:

  • Apache HTTP server benchmarking tool: não é apenas para o Apache e deve ser usada com frequência para verificar se a performance da aplicação está conforme o esperado;
  • monit: utiliitário open source e gratuito para o gerenciamento e monitoração de processos, programas, arquivos, diretórios e filesystems em um sistema UNIX;
  • webpagetest.org: apresenta informações detalhadas sobre a performance client-side e o que você deve fazer para melhorá-la.

[Crédito da imagem: Performance – Acuity Business Solutions, Performance – ShutterStock]

Autor

Engenheiro eletrônico e de computação pela UFRJ e mestre em informática pela PUC-Rio, atuo desde 2005 como engenheiro de software na globo.com tendo desenvolvido aplicações web de alta performance e escaláveis como o globoesporte.com e também o fanstasy game Cartola FC.

Victor Pantoja

Comentários

1 Comment

  • Oi Victor.
    Para mim que não sou programador e sim um Evangelista de Computação em Nuvem, chamou a atenção a questão da escalabilidade não estar ligada a linguagem e sim a arquitetura, o que concordo plenamente com você.
    Acrescento aí a escolha de uma hospedagem capaz de escalar a aplicação, que pode ser na Amazon, se você for capaz de configurar Elastic Load Balance, CloudWatch, puppet entre outros, ou partir para uma solução de plataforma como Heroku e aqui em terras brasileiras temos a Getup Cloud.
    Falando em banco de dados, Amazon RDS tem sido minha principal indicação quando se trata de um banco que necessite performance.

You must be logged in to post a comment.

Busca

Patrocínio

Publicidade



Siga-nos!

Newsletter: Inscreva-se

Para se inscrever em nossa newsletter preencha o formulário.

Artigos Recentes