Tuesday, August 12, 2008

Лекарство от регулярно падающего mongrel

При развертывании любого RoR проекта приходиться иметь дело с mongrel, а в случае серьезного проекта и с mongrel cluster. Как извесно, mongrel вещь сильно глюканутая: немногопоточная, часто память течет. В следствии этого появилась идея объединить несколько экземпляров в один кластер и привизать его к балансировщику nginx/apache. После этого жить стало лучше, но и кластер склонен к падению (в зависимости от типа запросов, монгрил может осилить от 500 до 1000 запросов, а потом утекает память или еще что случается), следовательно дела все равно плохо. Проблема заключается в том чтобы не доводить никого до плачевного состояния и последовательно рестартить по одному экземпляру за раз. 

Решение: каждые экземпляр рестартим раз в 10 минут, в случае с сервером работающем под высокой нагрузкой рекомендую каждые 5 минут. Кроме всего прочего скрипт живет в виде демона, которого не сложно положить в автостарт.

#!/usr/bin/ruby

pid = fork do
  cluster_size = `echo $CLUSTER_SIZE`.to_i
  life_time = 600 #10 mins
  span = life_time.to_f / cluster_size
  intance = 0 # mongrel id
  loop do
    mongrel_id = 3000+intance
    `mongrel_rails stop --pid log/mongrel.#{mongrel_id}.pid `
    sleep 10
    `mongrel_rails start -d -p #{mongrel_id} --pid log/mongrel.#{mongrel_id}.pid`
    intance+=1
    intance=0 if intance == cluster_size
    sleep span.to_i
  end
end
puts pid
Process.detach(pid)

No comments: