29
akitaonrails.com and God!
by AkitaOnRails on Jan.29.2008 at 06:40pm
Alguns devem ter notado que meu site ficou fora do ar por um bom tempo hoje. Isso aconteceu em outros dias. A razão: meus dois pobres mongrels estavam batendo no teto de memória da minha VPS (256Mb) e parando com erro de Out of Memory.
Eles começam razoavelmente pequenos, com uns 30Mb, rapidamente sobem para uns 70Mb, mas assim que ambos atingem mais de 120Mb cada, eles morrem. Daí só entrando e reiniciando manualmente. Obviamente isso não é prático :-)
Entra DEUS !! ... Quero dizer GOD
God é mais ou menos como outro mais conhecido, o Monit, mas acho que God é mais simples :-) Vamos ver se é bom.
Acabei de configurar ele no meu VPS, vamos ver se ele se segura. Eu usei basicamente a configuração de exemplo no site deles. No meu site ficou assim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# run with: god -c /etc/god.conf RAILS_ROOT = "/home/www/railsapp/current" %w{4000 4001}.each do |port| God.watch do |w| w.name = "akitaonrails-mongrel-#{port}" w.interval = 30.seconds # default w.start = "mongrel_rails start -c #{RAILS_ROOT} -p #{port} \ -P #{RAILS_ROOT}/tmp/pids/mongrel.#{port}.pid -d" w.stop = "mongrel_rails stop -P #{RAILS_ROOT}/tmp/pids/mongrel.#{port}.pid" w.restart = "mongrel_rails restart -P #{RAILS_ROOT}/tmp/pids/mongrel.#{port}.pid" w.start_grace = 10.seconds w.restart_grace = 10.seconds w.pid_file = File.join(RAILS_ROOT, "tmp/pids/mongrel.#{port}.pid") w.behavior(:clean_pid_file) w.start_if do |start| start.condition(:process_running) do |c| c.interval = 5.seconds c.running = false end end w.restart_if do |restart| restart.condition(:memory_usage) do |c| c.above = 90.megabytes c.times = [3, 5] # 3 out of 5 intervals end restart.condition(:cpu_usage) do |c| c.above = 50.percent c.times = 5 end end # lifecycle w.lifecycle do |on| on.condition(:flapping) do |c| c.to_state = [:start, :restart] c.times = 5 c.within = 5.minute c.transition = :unmonitored c.retry_in = 10.minutes c.retry_times = 5 c.retry_within = 2.hours end end end end |
Para iniciar apenas:
god -c /etc/god.conf
E para finalizer:
god quit
E posso fazer comandos como estes:
> god status
akitaonrails-mongrel-4000: up
akitaonrails-mongrel-4001: up
> god restart akitaonrails-mongrel-4001
Sending 'restart' command
.....
The following watches were affected:
akitaonrails-mongrel-4001
O próprio God consome seus 10Mb de RAM. Tecnicamente, com isso ele deve reiniciar os processos automaticamente quando eles atingirem os tetos de memória e cpu que eu coloquei acima. Veremos se isso minimiza o downtime do meu blog :-)
Meu VPS está configurado com o CentOS (que é um Fedora “enterprise level” vamos dizer). Para que o God se inicie a cada restart da máquina, precisamos definir o serviço. Primeiro, o arquivo /etc/init.d/god:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#!/bin/bash
#
# God
#
# chkconfig: - 85 15
# description: start, stop, restart God (bet you feel powerful)
#
GOD_CONF=/etc/god.conf
PID_DIR=/var/run/god
PID_FILE=$PID_DIR/god.pid
LOG_FILE=/var/log/god.log
GOD_PATH=/usr/local/bin/god
USER=root
PATH=$PATH:/usr/local/bin
RETVAL=0
# Gracefully exit if the controller is missing.
if ! [ -e $GOD_PATH ]; then
echo "$GOD_PATH not found"
exit 0
fi
# Go no further if config directory is missing.
if ! [ -e "$GOD_CONF" ]; then
echo "$GOD_CONF not found"
exit 0
fi
case "$1" in
start)
# Create pid directory
if ! [ -d "$PID_DIR" ]; then
mkdir -p $PID_DIR
chown $USER:$USER $PID_DIR
fi
$GOD_PATH -P $PID_FILE -l $LOG_FILE
$GOD_PATH load $GOD_CONF
RETVAL=$?
;;
stop)
kill `cat $PID_FILE`
RETVAL=$?
;;
restart)
kill `cat $PID_FILE`
$GOD_PATH -P $PID_FILE -l $LOG_FILE
$GOD_PATH load $GOD_CONF
RETVAL=$?
;;
status)
RETVAL=$?
;;
*)
echo "Usage: god {start|stop|restart|status}"
exit 1
;;
esac
exit $RETVAL
|
O arquivo Ruby do God que mostrei acima, coloquei em /etc/god.conf. Agora falta configurar o chkconfig para colocar o serviço nos service levels certos:
chmod +x /etc/init.d/god
chkconfig --add god
chkconfig --level 2345 god on
Finalmente, iniciar o serviço:
/etc/init.d/god start
Eu fiquei muito mal acostumado com shared hosting, agora que é VPS eu mesmo preciso botar a mão na massa de vez em quanto. Felizmente soluções como o God facilitam minha vida.






Akita, quantas visitas tem o seu site diariamente?
Sei lá.. de novo o mesmo papo que “rails não escala”.. mas sinceramente acho que ainda está muito fraco.
Um blog não deveria ficar caindo toda hora por causa disso. Se tivesse 10.000 acessos por dia… até vai lá, mas acredito que não seja esse valor (sem menosprezar o seu blog, que é muiiito bom).
Não quero criar flame ou gerar muita discussão.. mas é que tem horas que desanima mesmo ler uma noticia como essa. :(
Com certeza estes problemas de escalabilidade do rails desanimam um pouco.
Mas acho que é questão de tempo para termos servidores de aplicação bem estáveis.
O pessoal do “core rails” é muito competente, tecnicamente, e também podemos dar nossas contribuições.
Ei, calma, o problema no meu blog foi erro meu, não do Rails. Com pouca memória – e nenhum cuidado da minha parte quanto a memory leaks – depois de algum tempo rola Out of Memory. Com o God ou Monit basta eles reciclarem o processo de tempos em tempos. Nada demais, além do mais o God levou poucos minutos para configurar.
Lembrando uma coisa já dita pelo Akita: isso é um blog, não um e-commerce. Se o blog fica fora do ar, o Akita não perde clientes, dinheiro nem recursos. Apenas umas visitas.
Se isso fosse qualquer coisa que envolvesse missão crítica (como uma loja ou uma startup), estaria hospedado em um servidor mais potente, sendo monitorado. Em último caso, teria 3 slices na EngineYard :-D
O problema não é que Rails não escala. São as pessoas que tendem a analisar sempre da perspectiva mais fácil.
De qualquer forma, 1 nginx e 2 mongrels segura meu site com folga. Só a RAM que é bem limitada (mongrel é um application server, compare com tomcat, não com mod_php).
@guilhermo, meu blog é muito pequeno mesmo, por isso que meu plano de VPS é o mais barato hehehe. Na média eu tenho pouco mais de 1.200 unique visitors/dia que dão cerca de 35 a 40 mil hits por dia. Mas só isso já me consome mais de 600Mb de banda por dia. Nos picos, quando eu lancei o screencast original por exemplo, aí o consumo de banda chegou a mais de 1Gb/dia.
Levando em conta o preço dos serves hoje em dia, um site profissional ponto.com escala na boa com uma farm de 4 quad cores com 8gb de ram em cada unidade
Curiosidade: o artigo mais lido foi a entrevista com o Adrian Holovaty. Em pleno feriado, dia 1o. de janeiro, tive mais de 4.500 unique visitors e mais de 140 mil hits. 30Gb de banda.
O acumulado deste mês (até hoje) é de 27 mil unique visitors e 1.3 milhões de hits. Uma média por dia de 1.600 unique visitors, 44 mil hits e 1 Gb por dia (e isso porque eu não tenho nenhum arquivo multimídia direto no meu site).
Meus parabéns.
Gente chata é outra coisa… :-)
http://validator.w3.org/check?uri=http%3A%2F%2Fwww.akitaonrails.com%2F2008%2F1%2F29%2Fakitaonrails-com-and-god
Validation Output: 5 Errors
Abraço
Olha, pode ser exagero da minha parte. Mas a partir do momento que você precisa reiniciar o servidor de uma coisa qualquer por ela só consome memória, isto para mim tem nome: memory leak.
E causar uma parada x vezes por dia porque ou o blog foi mal feito, ou porque o Ruby não consegue gerenciar memória, isto é péssimo.
É a ASG: Administração de Servidor pela Gambiarra.
@derico, sim, claro e só você sabe disso :-) Talvez este artigo lhe ajude a compreender que o buraco é mais embaixo.