god 사용해서 mongrel들 감시하기
설치에 대해서는 god 사용하기 를 참조할 것.
config 파일 생성
god config 파일 app_name.god 을 다음과 같이 만들자.
- RAILS_ROOT = "/RAILS/ROOT/PATH"
PID_DIR = "#{RAILS_ROOT}/tmp/pids"
LOG_DIR = "#{RAILS_ROOT}/log" - %w{3001 3002}.each do |port|
God.watch do |w| - w.group = "group_name"
w.name = "myapp-mongrel-#{port}"
w.interval = 30.seconds # default
w.start = "mongrel_rails start -c #{RAILS_ROOT} -p #{port} \
-P #{PID_DIR}/mongrel.#{port}.pid -d -l #{LOG_DIR}/mongrel.#{port}.log -e production"
w.stop = "mongrel_rails stop -P #{PID_DIR}/mongrel.#{port}.pid"
w.restart = "mongrel_rails restart -P #{PID_DIR}/mongrel.#{port}.pid"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.pid_file = File.join(PID_DIR, "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 = 150.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 - restart.condition(:http_response_code) do |c|
c.host = '127.0.0.1'
c.port = port
c.path = '/'
c.code_is_not = 200
c.timeout = 10.seconds
c.times = [3, 5] # 3 out of 5 intervals
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
간단한 설명(자세한 설명은 god home 을 참조)
- %w{3001 3002}.each do |port|
=> port 3001, 3002 에 대해서
- God.watch do |w|
- w.group = "group_name"
- w.name = "myapp-mongrel-#{port}"
w.interval = 30.seconds # default
w.start = "mongrel_rails start -c #{RAILS_ROOT} -p #{port} \
-P #{PID_DIR}/mongrel.#{port}.pid -d -l #{LOG_DIR}/mongrel.#{port}.log -e production"
w.stop = "mongrel_rails stop -P #{PID_DIR}/mongrel.#{port}.pid"
w.restart = "mongrel_rails restart -P #{PID_DIR}/mongrel.#{port}.pid"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.pid_file = File.join(PID_DIR, "mongrel.#{port}.pid")
=> 감시 process를 생성
- w.group : 이녀석이 속한 그룹.
- w.name : 감시 process의 이름
- w.interval : 30초 간격으로 감시를 수행
- w.start : rails 시작 명령
- w.stop : rails 정지 명령
- w.restart : rails 재시작 명령
- w.start_grace : 시작시킨 다음 10초동안은 감시하지 않겠음.
- w.restart_grace : 재시작 시킨 다음 10초 동안은 감시하지 않겠음.
- w.pid_file : 감시하고자 하는 process의 pid 를 가지고 있는 파일.
- w.behavior(:clean_pid_file)
=> rails를 시작하기 전에 pid 파일이 존재하면 삭제, pid 파일만 있고 process는 죽은 경우 rails가 시작되지 않는 것을 방지하기 위해.
rails 가 살아 있는 경우에는 god를 통해 start 명령이 수행되지 않는다는 가정을 전제하고 있음.
- w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
end
end
rails가 5초동안 죽어 있으면 시작시키겠다.
- w.restart_if do |restart|
restart.condition(:memory_usage) do |c|
c.above = 150.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 - restart.condition(:http_response_code) do |c|
c.host = '127.0.0.1'
c.port = port
c.path = '/'
c.code_is_not = 200
c.timeout = 10.seconds
c.times = [3, 5] # 3 out of 5 intervals
end
end
다음 경우에 재시작 시키겠다.
- 150MB의 메모리를 사용하는 일이 5번 검사하는 동안 3회 발생하는 경우
- CPU 정유 50%이상인 경우가 5회되는 경우
- http://127.0.0.1:port 로 보낸 HTTP request의 결과가 200 이 아니거나
5회 요청중 3번이 10초이상 지체되는 경우
- 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
=> 시작 혹은 재시작 요청이 5분동안 5회 반복되면 일단 감시를 중지하겠음. ( 원래 안되는 건데 계속 살리려고 하는 미련한 짓은 하지 않겠다. )
10분 후에 감시를 다시 시작할 텐데, 이번에도 5분동안 같은 요청이 5회반복되면 감시를 중지.
다시 10분 후에 감시를 시작하는데 이 짓을 2시간동안 5회반복하면 감시를 완전히 중지.
실행
god를 실행하자.(첫번째 실행할 때는 동작을 안하더라..)
- sudo god -c /PATH/TO/app_name.god
-D 옵션을 이용하면 데몬으로 실행시키지 않기 때문에 디버깅하기 용이하다.
감시하고 있는 process들의 상태를 보자
- sudo god status
모니터를 잠시 중지하자.
- sudo god unmonitor PROCESS_NAME
PROCESS_NAME 대신 GROUP_NAME을 줄 수도 있다.
모니터하고 있는 rails를 재시작시키자.
- sudo god restart PROCESS_NAME
god를 종료한자
- sudo god quit
더 자세한 내용은 헬프를 참조
- god -h
오류가 발생했을 때 알림 메일 보내기
mongrel 에 예기치 않은 에러가 발생해서 mongrel이 죽었다가 다시 살아나는 경우 관리자 혹은 개발자에게 알림 메일이 전송된다면 멋진 일일 것이다.
다음과 같이 메일 설정을 적어둔다.
- God::Contacts::Email.message_settings = {
:from => 'god@example.com'
}
God::Contacts::Email.server_settings = {
:address => "smtp.example.com",
:port => 25,
:domain => "example.com",
:authentication => :plain,
:user_name => "john",
:password => "s3kr3ts"
}
그리고 메일을 받을 사람도 추가한다.
- God.contact(:email) do |c|
c.name = 'chang'
c.email = 'tom@example.com'
end
그리고 메일을 발송하고 싶은 조건에 notify를 추가해 메일을 발송하도록 하자.
- w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
c.notify = 'chang'
end
end
만약 메일 서버로 gmail 혹은 TLS를 사용하는 메일 서버를 사용하고 있다면?
이 방법은 지저분해 보이지만 어쨋든 동작한다.
[Rails] gmail 서버를 통해 ActionMailer로 메일보내기 를 참조해서 /usr/lib/ruby/gems/1.8/gems/god-0.7.0/lib에 smtp_tls.rb 생성하자.
/usr/lib/ruby/gems/1.8/gems/god-0.7.0/bin/god 에 다음을 추가한다.
- require 'smtp_tls'
물론 God::Contacts::Email.server_settings 도 적당하게 변경한다.
Comments (0)