1

我即将在生产中使用 foreman 和upstart export来启动一些无限的 rake 任务。

我不起眼的“守护进程”就这么简单:

task magic: :environment do
  loop do
    make_stuff_happen

    sleep 10
  end
end

我想知道工头在被要求重新启动时是否不只是杀死进程(例如 capistrano 部署),因为我不希望因此而发生任何损坏的操作。

如果是这样如何预防呢?

4

1 回答 1

6

如果您进行导出,您可能在配置上有一个文件, 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'

这基本上是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 进程的问题是,答案是肯定的,它将通过向 rake 进程发送 SIGTERM 来终止该进程。

默认情况下,当 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

然后如果你运行它

$ rake magic
Running the task wit PID 29527
doing some magic..

单独的终端上,您可以使用给定的 PID 将 SIGTERM 发送到 rake 进程。它会抛出异常

$ kill 29527

在上一个终端上你会得到

...                         
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)

所以这基本上是 rake 死了。它会立即停止一切。do_some_magic例如,如果当前正在执行 DB 操作,您可能会留下不一致的状态。

你当然可以处理这个信号来执行一些清理工作。如果您想等到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                                        

并再次运行它..

$ rake magic
Running the task wit PID 30150                     
doing some magic..                                 

并且在分离器终端上,您再次使用 pid 终止进程

$ kill 30150

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

....
doing some magic..             
SIG TERM received.             
shutting down..., exiting loop 

结论

  • foreman export 只会创建一个 ubuntu upstart 脚本。
  • 重启机制将由操作系统处理。将 SIGTERM 发送到进程。
  • 它依赖于实际过程来维护系统的状态。
  • 默认情况下,Rake 不处理 SIGTERM。您必须自己做以确保任务是否被中断,您需要进行清理以确保系统状态没有损坏

希望它有所帮助

于 2013-08-10T09:50:14.667 回答