PHP 5.3, PHP-FPM, XCache, Nginx no Debian Lenny – Performance extrema

janeiro 15th, 2010 by caferrari Leave a reply »

Neste post vou exemplificar os passos para configurar um Webserver que consome poucos recursos e é extremamente rápido no Debian Lenny.

PHP-FPM: é um gerenciador de processos CGI do php, similar ao Phpcgi, porém com várias vantagens como:

  • Gerenciador de Processos muito eficiente, com capacidade de parar e iniciar seus deamons caso necessário
  • Possibilidade de Iniciar processos com usuários diferentes e com arquivos php.ini diferentes
  • Uploads otimizados
  • Capacidade de reinicializar processos caso ocorra algum problema
  • Escalabilidade de processos, ele pode criar mais processos de acordo com a demanda
  • e muito mais.

XCache: é um gerenciador de cache, que armazena os scripts php em opcode para uso futuro, é extremamente rápido e muito usado no mundo em servidores com alta demanda.

Nginx: Conheci este webserver lendo o blog da boo-box, ele é um Servidor web e proxy reverso extremamente veloz e que vem ganhando mercado nos últimos meses devido a sua facilidade de uso e capacidade de carga.

Market Share de navegadores no final de 2009

Para agilizar a configuração, vamos usar alguns pacotes (php5.3, php-fpm) pré compilados e mantidos www.dotdeb.org. os testes que eu realzei usando estes pacotes tiveram um ganho de performance enorme.

Instalação:

Vamos começar adicionado os repositórios do dotdeb no /etc/apt/sources.list:

deb http://php53.dotdeb.org stable all
deb-src http://php53.dotdeb.org stable all

Vamos instalar os pacotes e algumas dependências para o nginx:

aptitude update
aptitude install php5-fpm php5-xcache php5-gd php5-curl \
php5-mysql php5-pgsql libssl-dev libpcre3-dev build-essential -y

Agora temos o php instalado, vamos compilar o nginx:

cd
mkdir src
cd src
wget http://nginx.org/download/nginx-0.7.64.tar.gz
tar -zxvf nginx-0.7.64.tar.gz
cd nginx-0.7.64
./configure --prefix=/usr/local/nginx --user=www-data --group=www-data \
    --without-mail_pop3_module --without-mail_imap_module \
    --without-mail_smtp_module --with-http_stub_status_module \
    --with-http_ssl_module --http-log-path=/var/log/nginx/access.log \
    --conf-path=/etc/nginx/nginx.conf  --pid-path=/var/run/nginx.pid
make
make install

Se tudo ocorreu bem, você já tem o nginx instalado, vamos apenas coloca-lo para inicializar automáticamente, crie o arquivo /etc/init.d/nginx e coloque o conteúdo:

#! /bin/sh
 
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO
 
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx
 
test -x $DAEMON || exit 0
 
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi
 
set -e
 
case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON || true
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON || true
        sleep 1
        start-stop-daemon --start --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  reload)
        echo -n "Reloading $DESC configuration: "
        start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
            --exec $DAEMON || true
        echo "$NAME."
        ;;
  configtest)
        echo -n "Testing $DESC configuration: "
        if nginx -t > /dev/null >&1
        then
          echo "$NAME."
        else
          exit $?
        fi
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart|reload|force-reload|configtest}" >&2
        exit 1
        ;;
esac
 
exit 0

depois vamos torna-lo executável e atualizar o rc.d:

chmod +x /etc/init.d/nginx
update-rc.d nginx defaults

Com isso o processo de instalação está concluído, vamos configurar!

Configuração do XCache

Coloque a seguinte configuração no arquivo /etc/php5/fpm/conf.d/xcache.ini:

; configuration for php xcache module
extension=xcache.so
 
[xcache.admin]
xcache.admin.user = "secom"
; xcache.admin.pass = md5($your_password)
xcache.admin.pass = ""
[xcache]
; ini only settings, all the values here is default unless explained
; select low level shm/allocator scheme implemenation
xcache.shm_scheme =        "mmap"
; to disable: xcache.size=0
; to enable : xcache.size=64M etc (any size > 0) and your system mmap allows
xcache.size  =                64M
; set to cpu count (cat /proc/cpuinfo |grep -c processor)
xcache.count =                 1
; just a hash hints, you can always store count(items) > slots
xcache.slots =                8K
; ttl of the cache item, 0=forever
xcache.ttl   =                 0
; interval of gc scanning expired items, 0=no scan, other values is in seconds
xcache.gc_interval =           0
; same as aboves but for variable cache
xcache.var_size  =            64M
xcache.var_count =             1
xcache.var_slots =            8K
; default ttl
xcache.var_ttl   =             0
xcache.var_maxttl   =          0
xcache.var_gc_interval =     300
xcache.test =                Off
; N/A for /dev/zero
xcache.readonly_protection = Off
; for *nix, xcache.mmap_path is a file path, not directory.
; Use something like "/tmp/xcache" if you want to turn on ReadonlyProtection
; 2 group of php won't share the same /tmp/xcache
; for win32, xcache.mmap_path=anonymous map name, not file path
xcache.mmap_path =    "/dev/zero"
 
; leave it blank(disabled) or "/tmp/phpcore/"
; make sure it's writable by php (without checking open_basedir)
xcache.coredump_directory =   ""
; per request settings
xcache.cacher =               On
xcache.stat   =               On
xcache.optimizer =            On
[xcache.coverager]
; per request settings
; enable coverage data collecting for xcache.coveragedump_directory and xcache_coverager_start/stop/get/clean() functions (will hurt executing performance)
xcache.coverager =          Off
; ini only settings
; make sure it's readable (care open_basedir) by coverage viewer script
; requires xcache.coverager=On
xcache.coveragedump_directory = ""

Configuração do Nginx

Edite o arquivo em /etc/nginx/nginx.conf:

user  www-data;
 
#Coloque quantos processos simultaneos, o ideal é um para cada nucleo do sistema:
worker_processes  4;
 
error_log  /var/log/nginx/error.log;
 
events {
    # numero de conexões simultaneas por worker
    worker_connections  1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    access_log  /var/log/nginx/access.log;
    sendfile        on;
    # isso é interessante, dá um ganho enorme na navegação, e o nginx aguenta tranquilamente
    keepalive_timeout  60;
    tcp_nodelay        on;
 
    ## Compressão
    gzip on;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_min_length  1100;
    gzip_buffers 16 8k;
    # mime types para zipar e adicionar header de cache
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/gif image/jpeg image/png;
    # Desabilita compressão em algumas versões do IE6
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    # Impede que servidores proxy mandem versões em gzip do arquivo para os IE6
    gzip_vary on;
 
    server {
	root  /var/www/;
	server_name     localhost;
	listen          80;
	location / {
		index  index.php index.html index.htm;
	}
 
	#error_page  404  /404.html;
	# redirect server error pages to the static page /50x.html
	error_page   500 502 503 504  /50x.html;
	location = /50x.html {
		root   /var/www/nginx-default;
	}
 
	# Joga requisições para arquivos .php para o php-fpm
	location ~ \.php$ {
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
		include fastcgi_params;
        	fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
        	fastcgi_param SERVER_NAME $http_host;
        	fastcgi_ignore_client_abort on;
	}
    }
}

Configuração do php-fpm

Edite o arquivo: /etc/php5/fpm/php5-fpm.conf e faça os ajustes que você achar interessante, aqui eu só aumento os max_childrens (Numero de clientes CGI) de 5 para 50, esta configuração depende do seu hardware.

Configuração do Logrotate

Vamos configurar agora o logrotate para não enchermos os discos com logs do nginx, edite o arquivo /etc/logrotate.d/nginx:

/var/log/nginx/*.log {
        daily
        missingok
        rotate 7
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.p$
        endscript
}

Finalizando

Agora que está tudo configurado, vamos reinicalizar os serviços:

/etc/init.d/php5-fpm restart
/etc/init.d/nginx restart

crie um arquivo /var/www/index.php e vamos testar o php:

 
e acesse: http://ip_do_servidor/
Advertisement

50 comments

  1. Erick disse:

    Fala ai Carlos,

    você fez alguma comparação de performance entre as soluções padrões (like, apache+php)?
    Tem algum gráfico de performance ou algum “vmstat 1″ p/ analisarmos?

    Mas foi uma ótima dica ! Obrigado!

  2. Diego disse:

    Também gostei do passo-a-passo. Porém faltou um comparativo como o Erick citou.
    Se der tempo vou testar essa solução em breve.
    Estou meio “viciado” em otimização de perfomance em servidores web. Ultimamente tudo que vejo sobre o assunto estou lendo e pesquisando.

    Obrigado pela contribuição

  3. Olá,

    kra, não fiz nenhum teste localmente, mas pesquisei vários no google e por isso decidi implementar…

    o que posso dizer, eh que nosso servidor (Do governo do Tocantins) é um Pentium 4, com 1gb de memória… com o apache ele começava a engasgar com 200 conexões… com o nginx já passou de 1000 conexões! e o uso da maquina não passa de 5%

    fiz até um post sobre isso: http://ferrari.eti.br/nginx-webserver-proxy-reverso-e-perfeito/ dá uma conferida

    Dá uma navegada nos sites:
    http://to.gov.br

    []‘s

  4. Silas Ribas disse:

    Salve,

    É Carlos só falta um comparativo entre apache2+php e nginx+php. Com configurações “iguais”, se otimiza em 1, faz o mesmo no outro.

    Está bem legal o artigo, valeu pela dica.

  5. sid disse:

    Thanks you very much for this tutorial, i was stopped by php-fpm install to make a full great install ! (only install nginx with fastCGI)

  6. Henrique Dias disse:

    olá Carlos. excelente post e blog também !
    pergunta básica: nada contra a distro Debian, muito pelo contrário, mas como tenho mais contato com Ubuntu, como você vê a possibilidade de implementação desta configuração em um servidor Ubuntu ?

  7. Diego disse:

    @Henrique Dias
    No Ubuntu não vai mudar muita coisa, aliás, acho que não muda nada visto que a base do Ubuntu é o próprio Debian.
    Os pacotes possivelmente serão os mesmos.

  8. Carlos André Ferrari disse:

    @Henrique Dias, @Diego

    Pode executar os processos sem nenhuma mudança no Ubuntu Server ou Desktop que funciona sem problemas.

    []‘s

  9. Diego disse:

    Acabei de instalar e testar a solução proposta e estou impressionado.
    Configurei o jMeter pra 2000 threads em 60 segundos e nem fez cócegas no servidor (virtual). Tudo bem que o teste foi acessar a página do PHP Info, mas mesmo assim a performance foi muito boa.
    Vou configurar outra máquina virtual de testes para replicar o mesmo ambiente, mas dessa vez com Apache e fazer um teste comparativo.

  10. Jose Nilton disse:

    Carlos, você já testou o Webserver Lighthttpd,
    pois estou testando e ele está aguentando o tranco, ou o cherokee -> http://www.cherokee-project.com/

    Esse ultimo também está muito rápido, mas prefiro o LIghtHTTPD

    benchmark:
    http://www.rkblog.rk.edu.pl/w/p/lighttpd-and-cherokee-benchmark/
    http://www.rkblog.rk.edu.pl/w/p/pylons-benchmark-various-servers/

  11. Jose Nilton disse:

    Tem outro benchmark Legal, mas eu prefiro o LightHTTPD, pois ele é mais fácil de instalar e configurar.

    http://www.alobbs.com/1345/Cherokee_0_8_1_benchmark.html

  12. Pessoal,

    Atendendo pedidos, e com ajuda do Ferrari na configuração, fiz um teste real: Apache X Nginx.

    Primeiro Server: CentOS+Apache+2core500+1GbRam
    Segundo Server: Ubuntu+Nginx+2core300+300MbRam

    Quem leva a melhor nessa? façam suas apostas. :)

    Coloquei o mesmo site nos 2 servers, um site de noticias, com MySQL e várias consultas na home. Medi o tempo de execução da home do site nos 2 servidores e peguei os maiores valores depois de algumas tentativas.

    Primeiro Server (apache): 0.6 segundos
    Segundo Server (nginx): 0.023 segundos

    Venceu o Nginx com 2600% de dianteira.

    Valeu Ferrari.

  13. Diego disse:

    Não consigo colocar o Zend Framework pra rodar com o Nginx. É possível? Alguém conseguiu? Ou tenho que fazer proxy com o Apache?

  14. caferrari disse:

    @Diego,

    é possivel sim, nunca usei o ZF, mas acredito que ele faz o uso do .htaccess, o htacces é do apache, no caso do nginx vc tem que configurar as rotas no arquivo de configuração, é tão simples quanto o metodo do apache e também é muito mais veloz.

    http://wiki.nginx.org/NginxHttpRewriteModule

    []‘s

  15. Diego disse:

    @caferrari Exatamente, o Zend Framework utiliza o .htaccess. Achei vários blogs com várias configurações diferentes para rodar o ZF no Nginx, porém nenhuma funciona. Estou sem tempo agora mas assim que possível vou verificar a wiki que você indicou. Obrigado.

  16. Diego disse:

    Eita. Acho que era problema na minha aplicação de testes. Peguei o exemplo do Quickstart http://framework.zend.com/manual/en/learning.quickstart.intro.html
    e funcionou.

  17. Clecio disse:

    Grande artigo, estou procurando uma alternativa mais rápida para rodar um sistema desenvolvido em PHP com JS (Ext).
    Como uso centos e esse usa o PHP 5.1.6 não tenho muita experiencia no Debia.
    Tenho uma duvida, como instalar suporte a MSSQL no PHP5?
    Muito obrigado.

  18. Ferrari, obrigado pelo ótimo tutorial. Encontrei esse script para benchmark: http://benchmarks.nickbarrett.org/

    E esse site com um comparativo entre PHP-FPM vs Spawn-FCGI vs FastCGI: http://vpsbible.com/php/php-benchmarking-phpfpm-fastcgi-spawnfcgi/

  19. caferrari disse:

    Obrigado pelo comentário @Rogério Madureira

    Bom apesar desse seu teste mostrar que o PHP-FPM é mais lento um pouco que as outras soluções, o FPM ainda tem vantagens.. como o spawn automático de threads dependendo da necessidade e os controles internos dele que garantem que seja fail-safe.

    []‘s

  20. Será que eu compreendi errado? havia entendido que o benchmarking havia apontado o PHP-FPM como a solução mais rápida, com tempo médio de 374ms para completar as operações do teste, contra 413ms do SPAWN-FCGI e 461ms do PHP-FASTCGI…

  21. caferrari disse:

    Não.. eu entendi errado mesmo… então pronto.. php-fpm é perfeito.. XD

    vlw!

  22. Great internet site. Lots of handy information and facts right here. I’m just giving them for some close friends ans in addition giving around tasty. And obviously, because of your own sweat!

  23. enlace disse:

    Nice weblog here! Additionally your site a lot up fast! What host are you using? Can I am getting your affiliate hyperlink to your host? I wish my site loaded up as fast as yours lol

  24. Нi there, constantly i usᥱd to check wеbsіte pоstѕ һerе іn thе еɑгⅼʏ ɦߋᥙгѕ
    in tɦe daуlіǥht, bесauѕе i ⅼονе tߋ ⅼеагn mⲟгᥱ and
    mߋге.

    Ϝеᥱⅼ fгеᥱ tߋ ѕսгf
    tⲟ mү աeƅ-ѕіtᥱ – rᥱνeгse mߋгtɡаցе (http://www.didudoda.com)

  25. bing disse:

    Great blog you have got here.. It’s difficult to find excellent writing like yours these days.
    I honestly appreciate individuals like you! Take care!!

  26. Michele disse:

    Hello, I think your blog might be having browser compatibility issues.
    When I look at your website in Chrome, it looks fine but when opening in Internet Explorer, it has some overlapping.
    I just wanted to give you a quick heads up!
    Other then that, terrific blog!

  27. Some really good information, Sword lily I detected this.

  28. Stanley disse:

    With a bachelor degree in Horticulture and Turf Grass Science, opportunities for management or supervisor positions will promote and increase your
    pay. These days, you will come across many students
    who would prefer to consider custom essays online.
    All those portals really are a research motor designed for you to uncover schools on-line or colleges together with on the internet studies.

  29. You completed some fine points there. I did a search on the subject
    matter and found the majority of people will consent with your website.

  30. Billie disse:

    Hello to every body, it’s my first go to see of this website; this weblog consists of amazing and actually fine material in favor
    of visitors.

  31. Hmm it seems like your blog ate my first comment (it was super
    long) so I guess I’ll just sum it up what I wrote
    and say, I’m thoroughly enjoying your blog. I as
    well am an aspiring blog writer but I’m still new to the whole thing.
    Do you have any points for beginner blog writers? I’d genuinely appreciate it.

  32. Adelaide disse:

    Heⅼlߋ.This post was extremely fascіnating, particularly becaսse
    I was looking for thoughts ߋn this іssue last couple of days.

  33. Hurrah, that’s what I was looking for, what a data!
    present here at this weblog, thanks admin of this site.

  34. Maravillo post. Gracias por publicarlo…Espero màs…

    Saludos

  35. Jestine disse:

    Definitely, whаt a gгeat blog and illuminating postѕ,
    I surely wwill bookmark your blog.Have ɑn awsome day!

  36. I’mnot thzt mսch of a internet reader to be Һonest but your blogs
    really nice, keep it up! I’ll go ahead and bookmark yolur website to ome back down tthе гoad.
    Many thanks

  37. Christin disse:

    Wow! Thnk you! I alwɑys needced to write oon my blog something like that.
    Can I tаke a part of your post tօ my site?

  38. Appreϲiate it f᧐or this grand post, I am ɡlad I noticed this websitе
    onn yahoo.

  39. guld disse:

    Tһis post provides clear idea in favor of the new users off bloցging, that really how tߋ do rᥙnning a blog.

  40. Ƅeing a blogger myself , i ccan sеe someone with cool potential,

  41. nmd uk disse:

    My husband and i ended up being so thankful when Michael could finish off his homework via the precious recommendations he had using your weblog. It’s not at all simplistic to just continually be giving out steps which often many people have been making money from. We really recognize we’ve got the blog owner to give thanks to for that. These explanations you have made, the easy blog menu, the relationships you give support to foster – it’s got all remarkable, and it is leading our son in addition to us recognize that that matter is fun, which is certainly seriously essential. Thank you for all!

Deixe uma resposta