2010-11-05 72 views
4

我有幾個nginx乘客部署的rails應用程序。我希望通過使用monit來監視這些應用程序。我如何使用monit監視這些應用程序?我應該監視nginx嗎?如何監控nginx乘客monit

+0

乘客2或乘客3.如果乘客3是獨立的或不是? – shingara 2010-11-05 08:08:06

+0

我使用乘客3,但從乘客2複製的配置。基本上,它是乘客2. – Chamnap 2010-11-05 09:19:10

+0

我不確定,但是,monit可以通過給PID來監視進程,因此您可以爲每個要監視的進程創建PID文件。 根據nginx的關注,您應該監控nginx作爲處理您的web請求並委派給其中一個乘客實例的主要流程。 – 2011-04-18 08:50:12

回答

3

這就是我解決這個問題的方法。首先,我加入到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每個實例。作爲pidfile的pid。

+1

我做了一個插件 - https://github.com/romanbsd/passenger_monit – Roman 2011-04-29 18:15:55

0

如果您希望讓它們繼續運行並在出現錯誤時讓它們重新啓動,那麼最好查看supervisord。 supervisord不是輪詢查看進程是否正在運行,而是實際運行進程本身。它運行的守護進程需要運行前臺才能正常工作,但它非常有效,並且會使服務比monit更快(monit通常會每分鐘輪詢一次,而supervisord會看到進程結束並立即重新啓動)。

我們在生產過程中使用supervisord運行我們所有的守護進程(nginx,beanstalkd,memcached,各種python服務等),然後使用monit監視supervisord作爲增加的備份。

+0

OP詢問了關於在Nginx Passenger下運行的Rails應用程序,這個問題在這個答案中沒有解決。 – Amir 2013-03-20 16:39:55

2

不知道是否爲時已晚發佈此但這是我如何使用的monit(5.14)停止客運Rails應用佔用過多內存:

的monit:

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" 

外殼腳本調用的monit(check_passenger_mem_usage):

#!/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 

大概不會,因爲它重新啓動整個Rails應用程序,但它至少可以防止導軌消耗大量MEMOR的最佳解決方案如果應用程序一次又一次地記憶密集。