Otimizacao de websites em PHP
-
Upload
felipe-ribeiro -
Category
Technology
-
view
8.225 -
download
2
description
Transcript of Otimizacao de websites em PHP
OTIMIZANDO A PERFORMANCE DE WEBSITES
EM PHP
FELIPE RIBEIRO
• Graduando (concluinte) em Ciência da Computação na UFCG
• Zend Certified Engineer - PHP5
• Trabalha como desenvolvedor Web e consultor com foco em performance e escalabilidade de Websites
• Experiência em grids computacionais e sistemas distribuídos
• Membro fundador do grupo PHP-PB
• Contribuidor do PHP e Mozilla Camino
OBJETIVO
• O objetivo desse mini-curso é apresentar alguns dos conceitos utilizados na otimização da performance e escalabilidade de web sites
• A abordagem utilizada será bottom-up, ou seja, iniciaremos de ajustes no servidor e back-end, para depois ajustarmos o front-end
• Em aplicações práticas, essa abordagem depende do problema.
• Quem está “sofrendo” mais? Servidor ou cliente?
Performance
a habilidade que uma aplicação tem de atingir um objetivo, como por exemplo responder no menor tempo possível
Escalabilidade
a habilidade de uma aplicação manter a performance quando a carga de trabalho aumenta.
PHP não é tão rápido...
Porém sua arquitetura shared-nothing simplifica a
escalabilidade
E PHP dificilmente é o gargalo
A maior parte do tempo é gasto no
banco de dados ou com o carregamento
do front-end
Sempre dá para espremer e melhorar
“OTIMIZAÇÃO PREMATURA É A RAÍZ DE TODOS OS PROBLEMAS”
DONALD KNUTH
É preciso medir antes de “adivinhar”
o que otimizar
É preciso medir antes de “adivinhar”
o que otimizar
E como medir?
Na medição, duas perguntas precisam
ser respondidas
1 - Quão rápido é meu sistema?
1 - Quão rápido é meu sistema?
Em aplicações Web, a métrica mais comum é o reqs/sec
1 - Quão rápido é meu sistema?
Essa pergunta é respondida com benchmarks
Testes de carga
Macintosh:~ felipe$ ab -c 10 -t 30 -k 'http://shoprizer.localhost/'This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking shoprizer.localhost (be patient)Finished 4379 requests
Server Software: Apache/2.0.59Server Hostname: shoprizer.localhostServer Port: 80
Document Path: /Document Length: 22320 bytes
Concurrency Level: 10Time taken for tests: 30.010 secondsComplete requests: 4379Failed requests: 0Write errors: 0Total transferred: 99436344 bytesHTML transferred: 97806240 bytesRequests per second: 145.92 [#/sec] (mean)Time per request: 68.532 [ms] (mean)Time per request: 6.853 [ms] (mean, across all concurrent requests)Transfer rate: 3235.74 [Kbytes/sec] received
Macintosh:~ felipe$ siege -b -t30s 'http://shoprizer.localhost/'** SIEGE 2.67** Preparing 10 concurrent users for battle.The server is now under siege...Lifting the server siege... done.Transactions: 4909 hitsAvailability: 100.00 %Elapsed time: 29.84 secsData transferred: 104.49 MBResponse time: 0.06 secsTransaction rate: 164.51 trans/secThroughput: 3.50 MB/secConcurrency: 9.93Successful transactions: 4909Failed transactions: 0Longest transaction: 2.28Shortest transaction: 0.00
2 - Por que meu sistema tem essa performance?
Profiling
2 - Por que meu sistema tem essa performance?
Xdebug arrebenta no profiling!
• Instale a extensão Xdebug
• Habilite a opção xdebug.profiler_enable caso queira que toda execução gere o log
• Ou a opção xdebug.profiler_enable_trigger para que o log só seja gerado quando você passar?XDEBUG_PROFILE na URL
• Rode o script que você quer analisar
• Abra o log gerado pelo Xdebug no KCacheGrind caso use Linux, ou no WebGrind em qualquer outra plataforma.
http://code.google.com/p/webgrind/
• xdebug_memory_usage( ) diz quanto de memória o script está usando no momento da chamada
• xdebug_peak_memory_usage( ) diz qual o valor máximo de memória que foi usada durante a execução
Ajustes nos servidores
APACHE
MOD_DEFLATE
• Comprime o arquivo com gzip antes de enviar (se o navegador suportar)
• O custo de processamento normalmente é compensado com a economia de banda
• Só compacte arquivos de texto (html, xml, css, js)
MOD_DEFLATE
• Configurando:
$ a2enmod deflate
/etc/apache2/mods-available/deflate.conf<IfModule mod_deflate.c>AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript</IfModule>
MOD_EXPIRES
• Diga ao visitante até quando ele pode usar a versão atual de um arquivo sem precisar acessar o servidor novamente
• Use o cache do cliente, economize requisições e dê a ele a impressão de mais rapidez
• mod_expires coloca no cabeçalho HTTP a data de expiração daquele arquivo
MOD_EXPIRES
$ a2enmod expires
No seu .htaccess ou configuração do site:
ExpiresActive OnExpiresDefault "access plus 30 days" ExpiresByType text/html "access plus 1 month 15 days 2 hours"ExpiresByType image/gif "modification plus 5 hours 3 minutes"
DIRECTORYINDEX
• No Apache você pode configurar o DirectoryIndex que especifica qual arquivo é o “index” de cada diretório
• Você pode especificar mais de um e o Apache segue a sequência até achar o que exista:
<Directory /var/www> DirectoryIndex index.html index.htm index.php</Directory>• Para isso, é feita uma syscall para verificar a existência dos arquivos
a cada requisição
DIRECTORYINDEX
• O impacto é pequeno mas podemos evitar isso
• Configure o DirectoryIndex para ir direto para o arquivo correto
<Directory /var/www> DirectoryIndex index.php</Directory>
Use um servidor a parte para arquivos estáticos
http://static.example.com
Algo mais leve também resolve...
Lighttpdnginxthttpd
PHP
APC
• PHP compila os arquivos (JIT) e gera um código intermediário (opcode) a cada execução
• Essa compilação pode ser evitada, para isso é necessário fazer cache do opcode
• A solução padrão é o APC
• Virá “built-in” no PHP6
APC
• Existem outras alternativas com o mesmo propósito
• XCache
• Zend Platform
APC
• A instalação é trivial, no Ubuntu basta executar :
# apt-get install php-apc
• Por padrão o cache do opcode já é habilitado
• O parâmetro apc.stat permite que o APC não cheque se o arquivo foi alterado (aumentando ainda mais a performance), o que é bom para sistemas em produção. Mas qualquer alteração implica num restart do Apache.
BANCOS DE DADOS
MySQL
MYSQL• MySQL é o SGBD mais comumente utilizado com o PHP
• Foi feito com foco em performance, mas com o tempo vem ganhando funcionalidades voltadas para integridade relacional e consistência dos dados
• Implementa um cache interno de queries
• Os principais engines são:
• MyISAM
• InnoDB
• Ambos usam índices organizados internamente em árvores B
• Qual escolher?
MYSQL - MYISAM
• Rápida para leitura
• Table-level locking
• Uma escrita trava todos os acessos paralelos à tabela
• INSERT DELAYED é não bloqueante e permite que seu PHP continue executando enquanto a query fica na fila para ser executada
• Índices FullText
MYSQL - MYISAM
• Menor consumo de memória e espaço em disco
• Utiliza recursos de cache do sistema operacional
MYSQL - INNODB
• Integridade relacional
• Chaves estrangeiras
• Row-level locking
• Na escrita, só é travado para acessos paralelos o registro que está sendo escrito
• Maior consumo de memória e espaço em disco
• Utiliza implementação própria de cache
ÍNDICES
ÍNDICES
• Índices agilizam as buscas e tornam as escritas mais lentas
• Transforme em índice todas as colunas que são utilizadas como parâmetro de consulta ou ordenação
• Remova o índice das colunas que não são utilizadas nessas situações.
TIPOS DE DADOS
TIPOS DE DADOS
• Não armazene números em VARCHAR
• Não armazene datas em VARCHAR
• Se o campo tem tamanho fixo use CHAR
• Ex.: Uma senha em MD5 (32) ou SHA1 (41)
• Economiza espaço e facilita as comparações
CACHE
CACHE
• Cache é a solução mais comum para otimização de performance em diversas áreas da computação
• Consiste em armazenar uma informação que é mais acessada num meio mais rápido do que a sua real origem.
• Por exemplo: Memória RAM serve de cache para o disco
CACHE
• Consulta a dados que não se alteram com muita frequência podem ser colocadas em cache. Por exemplo:
• Um site de notícias não precisa acessar o banco todas as vezes que uma mesma notícia precisa ser exibida.
• Um site que agrega conteúdo de vários outros não precisa consultar as APIs a cada acesso dos seus usuários. Ele pode manter um cache local.
CACHE
• Iremos discutir a implementação de 4 tipos de cache:
• Smarty (Cache em disco)
• APC (Cache em memória)
• Memcache (Cache em memória em ambiente distribuído)
• Funky Caching (Cache em disco com a criação de arquivos estáticos)
SMARTY
• Smarty é uma biblioteca muito popular de “template engine”
• Porém ela também oferece a funcionalidade de cache dos templates já com as informações agregadas
• Gerando no disco um arquivo específico para cada registro “cacheado”
• Você pode setar um TTL para o objeto em cache
SMARTY
<?phprequire 'smarty/Smarty.class.php';
$id = (int) $_GET['id'];$smarty = new Smarty();$smarty->caching = 1;
if(!$smarty->is_cached('noticia.tpl',$id)) { //Carrega do banco de dados}$smarty->display('noticia.tpl',$id);
http://smarty.net/manual/pt_BR/caching.php
APC
• O mesmo APC que faz cache do Opcode também faz cache de objetos na memória
• apc.shm_size determina quanto de memória o APC pode usar para armazenar objetos, quando esse espaço é ocupado, os que foram usados a mais tempo são removidos (LRU)
• Você pode setar um TTL para o objeto em cache
APC
<?php$id = (int) $_GET['id'];$cache_id = "noticia::$id";
if(!($noticia = apc_fetch($cache_id))) {
$noticia = new Noticia($id);
//Armazena o valor no cache em memória do APC apc_store($cache_id, $noticia);}
...
http://br.php.net/apc
MEMCACHE
• O Memcache independe do PHP, é executado como um daemon externo
• Conecta-se via sockets, e por isso não é indicado para grandes objetos
• Utiliza também a política do LRU para remoção
• Você pode setar um TTL para o objeto em cache
MEMCACHE<?php$id = (int) $_GET['id'];$cache_id = "noticia::$id";
$memcache = new Memcache();$memcache->connect('localhost', 11211);
if(!($noticia = $memcache->get($cache_id))) { $noticia = new Noticia($id); $memcache->set($cache_id,$noticia);}
...
http://br.php.net/memcache
MEMCACHE
• Memcache também pode ser utilizado como mecanismo para armazenamento de dados de sessão.
• Isso permite que se tenha vários servidores Web e independente de qual servidor trate a requisição do usuário, pode-se acessar os dados de sessão que estão no servidor Memcache, basta setar no php.ini:
session.save_handler = memcachesession.save_path = "tcp://host_do_memcache:11211"
FUNKY CACHING
• Funky Caching é uma técnica não muito elegante mais muito eficiente
• Consiste em criar arquivos html estáticos sob demanda
• Usada no próprio site php.net
FUNKY CACHING
• No .htaccess ou outro arquivo de configuração do seu site no Apache, especifique como página de erro 404 um script PHP que é responsável por criar as páginas que não estão em cache.
• Por exemplo, no diretório http://www.example.com/noticias/ poderíamos criar um .htacces com a regra:
ErrorDocument 404 /noticias/gera_cache.php
FUNKY CACHING
• No gera_noticias.php faríamos tratamento da URL que foi requisitada e criaríamos o arquivo caso seja possível, por exemplo:
• http://www.example.com/noticias/1234.html indica que o usuário quer acessar a notícia de id 1234
• O PHP cria esse arquivo e nos próximos acessos o html existirá e o PHP não será mais chamado, pois não ocorrerá o erro 404.
FUNKY CACHING<?php$id = basename($_SERVER['REDIRECT_URL'], '.html');
/* Acessa a página dinâmica */$html = file_get_contents(sprintf("http://www.example.com/noticias.php?id=%d",$id));/* O ideal é fazer algum tratamento de erros, para evitar acriação de arquivos para ids inválidos */
/* Exibe o conteúdo */header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));echo $html;
/* Salva o conteúdo em um arquivo .html */file_put_contents(sprintf(dirname(__FILE__)."/%d.html", $id), $html);
E A NÍVEL DE BROWSER?
FIREBUG + YSLOW
• São plugins para o Mozilla Firefox
• Fazem análise para depuração (Firebug) e otimização (YSlow) de toda a parte client-side
• YSlow foi desenvolvido pelo Yahoo Performance Team
FIREBUG - NETMostra o tempo de requisição, espera e download de cada
componente da página
FIREBUG - NET
YSLOW - GRADEAnalisa vários critérios da página, dá “notas” e dá dicas de como
melhorar
YSLOW - GRADE
YSLOW - COMPONENTSPermite analisar a carga de cada componente carregado
YSLOW - COMPONENTS
YSLOW - STATISTICSMostra como a carga está proporcionalmente dividida entre os
componentes da página, com cache limpo e “quente”
YSLOW - STATISTICS
YSLOW - TOOLSFerramentas para compressão de Javascript, imagens, geração de
relatórios e análise de código
YSLOW - TOOLS
REFERÊNCIAS
• PHP - Simple is Hard - Rasmus Lerdorf - http://talks.php.net/show/w2e09
• Alta performance em Web Sites - Souders - Editora O’Reilly