Rails 为什么在 rails 项目中 touch /tmp/restart.txt 这个文件就可以达到更新服务的目的?

lb563 · 2012年02月22日 · 最后由 baypm2014 回复于 2016年05月24日 · 8998 次阅读

一般在 rails+nginx+passenger 在修改部分代码后,通常 touch 一下/tmp/restart.txt 就可以更新项目,这个和 nginx -s reload 的作用是一样的,我想问一下。这个做的原理是什么呢?

Phusion Passenger checks whether the timestamp of this file has changed in order to determine whether the application should be restarted.

通过对比时间戳来判断是否需要重启

nginx -s reload 是重启 Nginx touch /tmp/restart.txt 是重启当前的 Rails 项目

Passenger 会检查这个文件,如果这个文件时间戳改变了,或者被创建或者移除,Passenger 就会 reload。

相关的实现可以在 passenger 代码中查看 needsRestart 这个函数:

https://github.com/FooBarWidget/passenger/blob/master/ext/common/ApplicationPool/Pool.h

我之前自己写的一个方法,用在常驻内存的 rake 里面,用来动态装载 yml 文件,以达到运行参数改动之后能及时生效,:

@timestamps = 0
@restart_file = "#{::Rails.root.to_s}/tmp/restart.txt"
@config_file = "#{::Rails.root.to_s}/config/robot.yml"

def timestamp_read(file)
  File.exist?(file) ? File.ctime(file).to_i : 1
end

def need_to_reload_config_file?(file)
  current = timestamp_read(file)
  return unless current > @timestamps

  @timestamps = current
end

def reload_config_file(file)
  config = YAML::load_file(file) if File.exist?(file)
  ......
end

使用:reload_config_file(@config_file) if need_to_reload_config_file?(@restart_file)

#3 楼 @zfjoy520 监控文件有个 gem fssm ( https://github.com/ttilley/fssm ,File System State Monitor),针对不同的系统和系统现有的 gem,使用不同的 backend

@willmouse @zhangyuan @zfjoy520 我有一个项目在 Prodution环境中用的是 passenger standalone,本地 capistrano 部署的脚本中

desc "Restart Application"
task :restart, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"
end

部署后发现页面不是最新的,所以要在服务器中 kill passenger standalone 掉再 start 下

passenger 确实有时会死掉的,即使你 Nginx stop 掉了,passenger 的进程还在

应该是 passenger 定期检测 restart.txt 文件的时间戳实现 但我想知道 passenger 多久 1 次去检测这个时间戳呢?

已经知道了,每次 request,回去 check 一次

当视图有变更时,通过 touch 居然没生效,诡异!还是通过 passenger 更新比较保险。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号