Ruby on rails 如何使用monit监控nginx乘客

Ruby on rails 如何使用monit监控nginx乘客,ruby-on-rails,nginx,monitoring,passenger,Ruby On Rails,Nginx,Monitoring,Passenger,我有几个由nginx乘客部署的rails应用程序。我希望使用monit来监视这些应用程序。如何使用monit监控这些应用程序?我也应该监视nginx吗?如果您希望保持它们运行,并在出现错误时让它们重新启动,您最好查看一下。supervisord实际上是运行进程本身,而不是轮询进程是否正在运行。它运行的守护进程需要在前台运行该进程才能工作,但它非常有效,并且会比monit更快地启动服务(monit通常每分钟轮询一次,而supervisord会看到进程结束并立即重新启动) 我们在运行所有守护进程(n

我有几个由nginx乘客部署的rails应用程序。我希望使用monit来监视这些应用程序。如何使用monit监控这些应用程序?我也应该监视nginx吗?

如果您希望保持它们运行,并在出现错误时让它们重新启动,您最好查看一下。supervisord实际上是运行进程本身,而不是轮询进程是否正在运行。它运行的守护进程需要在前台运行该进程才能工作,但它非常有效,并且会比monit更快地启动服务(monit通常每分钟轮询一次,而supervisord会看到进程结束并立即重新启动)


我们在运行所有守护进程(nginx、beanstalkd、memcached、各种python服务等)的生产环境中使用supervisord,然后使用monit来监视supervisord作为附加备份

我就是这样解决的。首先,我在application.rb中添加了:


# Monit support
if defined?(PhusionPassenger)
  require 'pidfile_manager'
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      # We're in smart spawning mode.
      PidfileManager.write_pid_file
    else
      # We're in conservative spawning mode. We don't need to do anything.
    end
  end

  PhusionPassenger.on_event(:stopping_worker_process) do
    PidfileManager.remove_pid_file
  end
end
然后我实现了PidfileManager:


module PidfileManager
  extend self

  BASENAME = '/var/tmp/rack.*.pid'

  def write_pid_file
    pid = Process.pid
    count = 1
    pidfile = nil
    go_over_pid_files do |file, saved_pid|
      file_id = file[/(\d+)/,1].to_i
      # Increase counter only if we met the same file id
      count += 1 if file_id == count
      # We're already there
      return if saved_pid == pid
      # Check if the process is alive
      res = begin
        Process.kill(0, saved_pid)
      rescue Errno::ESRCH
        nil
      end
      # It's dead, reuse
      unless res
        pidfile = file
        break
      end
    end
    pidfile ||= BASENAME.sub('*', count.to_s)
    File.open(pidfile, 'w') {|f| f.write(pid.to_s)}
  end

  def remove_pid_file
    pid = Process.pid
    go_over_pid_files do |file, saved_pid|
      if pid == saved_pid
        File.unlink(file)
        break
      end
    end
  end

  private
  def go_over_pid_files
    Dir[BASENAME].each do |file|
      saved_pid = File.read(file).to_i
      yield file, saved_pid
    end
  end

end

然后,您只需告诉monit使用/var/tmp/rack.X.pid作为pid文件来监视每个实例。

不确定发布此消息是否为时已晚,但这就是我使用monit(5.14)阻止客运铁路应用程序消耗太多内存的方法:

莫尼特:

check program ourapp_live with path     "/usr/local/bin/check_passenger_mem_usage ourapp 500" as "ourappuser"
 if status != 0 then alert
 if status != 0 then restart
 start program = "/bin/touch /var/www/vhosts/ourapp/railsapp/current/tmp/restart.txt"
 stop program = "/bin/true"
shell脚本monit调用(检查乘客和成员的用法):


可能不是最好的解决方案,因为它会重新启动整个rails应用程序,但至少它可以防止rails在应用程序内存密集时消耗大量内存。

passenger 2或passenger 3。如果乘客3是独立的还是非独立的?我使用乘客3,但配置是从乘客2复制的。基本上,它是passenger 2。我不确定,但是,monit可以使用give PID监视一个进程,这样您就可以为要监视的每个进程创建PID文件。根据nginx关注点,您应该监控nginx,将其作为处理web请求的主要流程,并将其委托给其中一个乘客实例。尝试此gem可以帮助您特别询问在nginx乘客下运行的Rails应用程序,本回答中未提及此问题。
#!/bin/bash
#
#
USER=$1
TRIGGER=$2

if [ -z $USER ] || [ -z $TRIGGER ]
then
    echo "missing args"
    echo "usage:"
    echo "         check_passenger_mem_usage username alert_threshold"
    echo
    echo "(alert_threshold is in mb)"
    echo
    exit 1
fi

MAX=`/usr/local/rvm/gems/ruby-1.8.7-p357/wrappers/passenger-memory-stats | grep $USER | awk '{print $2}' | sort -n | tail -1|cut -d. -f1`

if [ "$MAX" -gt $TRIGGER ]
then
    echo
    echo "${USER}: We got a runaway! Gobbling ${MAX} mb"
    echo
    exit 1
else
    echo
    echo "Max is ${MAX}"
    exit 0
fi