工头是否正常重启?

Rya*_*yan 1 capistrano ruby-on-rails foreman

我即将使用工头在生产中使用upstart导出来开始一些无限的rake任务.

我简陋的"守护进程"就像这样简单:

task magic: :environment do
  loop do
    make_stuff_happen

    sleep 10
  end
end
Run Code Online (Sandbox Code Playgroud)

我想知道工头是否在被要求重启时不会直接杀死进程(例如,capistrano deploy),因为我不希望因此而发生任何损坏的操作.

如果是这样,如何预防呢?

ahm*_*hmy 5

如果你进行导出,你可能在配置上有一个app-jekyll-1.conf 包含这样的东西的文件

start on starting app-jekyll                                                                                               
stop on stopping app-jekyll
respawn

exec su - username -c 'cd /some/directory; export PORT=5000; bundle exec jekyll serve -w >> /tmp/a    pp.log/jekyll-1.log 2>&1'
Run Code Online (Sandbox Code Playgroud)

这基本上是ubuntu新贵的配置.

现在,当您使用upstart重新启动服务时,它实际上会调用 initctl restart

http://upstart.ubuntu.com/cookbook/#restart

调用initctl restart会将SIGTERM信号发送给作业

https://serverfault.com/questions/189780/what-signal-does-upstart-initctl-use-to-restart-a-job

现在清理资源取决于程序在收到SIGTERM信号时是否进行清理.

当你要求重启时,工头是否会杀死rake进程的问题,然后答案是肯定的,它会通过将SIGTERM发送到rake进程来终止进程.

默认情况下,当rake收到SIGTEM时,它将退出该进程.

例如,如果这是你的Rakefile

def do_some_magic
  puts "doing some magic.."
  sleep 5
end

task :magic do
  puts "Running the task wit PID #{$$}"
  loop do
    do_some_magic

    sleep 5
  end
end
Run Code Online (Sandbox Code Playgroud)

如果你运行它

$ rake magic
Running the task wit PID 29527
doing some magic..
Run Code Online (Sandbox Code Playgroud)

Separate终端上,您可以使用给定的PID将SIGTERM发送到rake进程.它会引发异常

$ kill 29527
Run Code Online (Sandbox Code Playgroud)

在上一个终端,你会得到

...                         
doing some magic..                                            
rake aborted!                                                 
SIGTERM                                                       
/tmp/foo/Rakefile:11:in `sleep'                               
/tmp/foo/Rakefile:11:in `block (2 levels) in <top (required)>'
/tmp/foo/Rakefile:8:in `loop'                                 
/tmp/foo/Rakefile:8:in `block in <top (required)>'            
Tasks: TOP => magic                                           
(See full trace by running task with --trace)
Run Code Online (Sandbox Code Playgroud)

所以这基本上是耙死了.它会立即阻止一切.do_some_magic例如,如果当前正在执行数据库操作,则可能会保持不一致状态.

您当然可以处理此信号以执行一些清理.如果你想等到do_some_magic完成,这就是你如何处理它

def do_some_magic                          
  puts "doing some magic.."                
  sleep 5                                  
end                                        

task :magic do                             
  puts "Running the task wit PID #{$$}"    
  loop do                                  
    do_some_magic                          

    if $shutdown                           
      puts "shutting down..., exiting loop"
      break                                
    end                                    
  end                                      
end                                        

trap "TERM" do                             
  puts "SIG TERM received."                
  $shutdown = true                         
end                                        
Run Code Online (Sandbox Code Playgroud)

并再次运行它..

$ rake magic
Running the task wit PID 30150                     
doing some magic..                                 
Run Code Online (Sandbox Code Playgroud)

并且在分离器终端上你再次使用pid杀死进程

$ kill 30150
Run Code Online (Sandbox Code Playgroud)

在你以前的终端上,这个过程就是这样的

....
doing some magic..             
SIG TERM received.             
shutting down..., exiting loop 
Run Code Online (Sandbox Code Playgroud)

结论

  • foreman export将只创建一个ubuntu upstart脚本.
  • 重启机制将由OS处理.哪个是将SIGTERM发送到该流程.
  • 它取决于维持系统状态的实际过程.
  • 默认情况下,Rake不处理SIGTERM.你必须自己做以确保任务是否被中断,你做清理以确保系统的状态没有被破坏

希望它有所帮助