Fork me on GitHub

The WebDevil

Enjoy development

“Посчастливилось” мне заполучить VPS с сайтом на битриксе. Из-за Zend Optimizer (сорсы покриптованы) нет возможности установить APC. Вроде бы умеет xcache работать вместе с ним, еще не проверял. Периодически апач съедает всю память, свап, и машинка умирает окончательно. Хуже то, что апач работает с mpm-prefork, то есть он порождает не потоки, а процессы. И при мониторинге виден родительский процесс, который занимает всего 13М памяти.

Вначале для рестарта апача в период дикого роста я пытался использовать monit, но результат был неадекватный – при указании memory > 90% он убивал его когда памяти была занята всего треть.

После monit я попробовал использовать god. Но он мониторит только один процесс, без его чайлдов. Вроде бы есть проект bluepill, который идейно растет из god. Но примеры найти оказалось проблематично, да и в процессе решил таки остаться с god.

Среди условий у god была обнаружена фича – :lambda. После недолгого размышления на bash была написана строка, показывающая занятый апачем процент памяти:

ps -e -o pmem,cmd | grep apache2 | grep -v grep | awk '{sum += $1;}END{print sum;}'

что сразу переродилось в

w.restart_if do |restart|
  restart.condition(:lambda) do |c|
    c.lambda = lambda{`ps -e -o pmem,cmd | grep apache2 | grep -v grep | awk '{sum += \$1;}END{print sum;}'`.to_i > 90}
  end
end

Итого конфиг для апача выглядит так:

God::Contacts::Email.delivery_method = :sendmail

God.contact(:email) do |c|
  c.name = 'maintainer'
  c.email = 'pager@sms.gate.isp'
end


God::Contacts::Email.format = lambda do |name, email, message, time, priority, category, host|
  < <-EOF
From: god
To: #{name} <#{email}>
Subject: Alert!
Date: #{Time.now.httpdate}
Message-Id: < #{rand(1000000000).to_s(36)}.#{$$}.#{self.message_settings[:from]}>

#{host} (#{priority}): #{message}
  EOF
end


%w{80}.each do |port|
  God.watch do |w|
    w.name = "apache2"
    w.pid_file = "/var/run/apache2.pid"
    w.interval = 10.seconds # default
    w.start = "/etc/init.d/apache2 start"
    w.stop = "/etc/init.d/apache2 stop"
    w.restart = "/etc/init.d/apache2 restart"
    w.start_grace = 10.seconds
    w.restart_grace = 20.seconds

    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(:lambda) do |c|
        c.lambda = lambda{`ps -e -o pmem,cmd | grep apache2 | grep -v grep | awk '{sum += \$1;}END{print sum;}'`.to_i > 90}
        c.notify = 'maintainer'
      end
    end
  end
end

Comments are closed.