如何在 Rails 中停止守护程序服务器?

Posted

技术标签:

【中文标题】如何在 Rails 中停止守护程序服务器?【英文标题】:How to stop a Daemon Server in Rails? 【发布时间】:2010-11-12 22:34:32 【问题描述】:

我正在使用以下方式运行我的 rails 应用程序

  $script/server -d webrick 

在我的 Ubuntu 系统上,上面的命令在后台运行 webrick 服务器。我可以使用 kill 命令杀死进程

  $kill pid

rails 是否提供任何命令来停止后台运行的守护程序服务器?

喜欢rails提供的启动服务器,谢谢。

编辑什么时候启动守护服务器合适?任何实时场景都会有所帮助谢谢

【问题讨论】:

【参考方案1】:

如果它有用,在 linux 上你可以找到哪个进程正在使用你可以使用的端口(在本例中为 3000):

lsof -i :3000

它也会返回 pid

【讨论】:

即使在 Mac/unix/bash... 是的。这非常有帮助。 lsof -i :3000 告诉我正在运行的 ruby​​ 的 PID kill $(lsof -i :3000 -t) - -t 选项代表 简洁,这意味着它只会输出进程 ID。 太棒了;这是我的 bash_aliases alias stopRails='kill -9 $(lsof -i :3000 -t)'alias startRails='rails server -d' (如果您不在应用程序目录中,将失败,但没关系)最后是 alias restartRails='stopRails && startRails' @Sudhi,你的解决方案太棒了 Rubyfied 版本:pid = `lsof -i :3000 -t`.chomp.to_i(@Gerry 对-t 标志的调用非常好,我今天学到了一些新东西!)【参考方案2】:

就像瑞恩说的:

你想要的 pid 在 tmp/pids/

可能 server.pid 是你想要的文件。

您应该能够运行kill -9 $(cat tmp/pids/server.pid) 来关闭一个守护服务器。

【讨论】:

lsof -i :3000 之后我得到了 ruby​​ 的 PID,然后是 kill -9 1406orWhateverThePIDofRubyWas - easypeasy - 谢谢! 是的,并且丢失了内存中但尚未在磁盘上的数据。【参考方案3】:

rake 任务怎么样?

desc 'stop rails'
task :stop do
    pid_file = 'tmp/pids/server.pid'
    pid = File.read(pid_file).to_i
    Process.kill 9, pid
    File.delete pid_file
end

使用 rake stop 或 sudo rake stop 运行

【讨论】:

仅在守护进程挂起时使用kill -9。否则,您将丢失 Active Directory 缓存中未刷新的数据。 可能是这样,但无论如何你应该只在开发中运行这样的服务器。【参考方案4】:

守护程序服务器的进程 ID 存储在您的应用程序目录 tmp/pids/ 中。您可以使用您的标准 kill process_id 与您在那里找到的信息。

【讨论】:

这是一个单行代码,您可以将其分配给 ~/.bashrc 文件中的别名:kill -9 $(lsof -i:3000) &> /dev/null&> 之后的部分是可选的——它只是抑制了 kill 命令的一些输出。 我建议不要运行它,因为您的浏览器可能会打开 3000 端口,因为它正在与您的 Rails 服务器通信。我以这种方式不小心杀死了 Chrome 几次。 :)【参考方案5】:

杀死 Ruby on Rails 默认服务器(即 WEBrick)的唯一正确方法是:

kill -INT $(cat tmp/pids/server.pid)

如果你运行的是 Mongrel,这就足够了:

kill $(cat tmp/pids/server.pid)

如果您的守护进程挂起,请使用kill -9。请记住kill -9 的含义——如果保存在 Active Record 缓存中的数据没有刷新到磁盘,您将丢失数据。 (就像我最近所做的那样)

【讨论】:

嗯……但是,正如另一篇文章所述,Rails 或 WEBrick 或其他人似乎忽略了所有更温和的信号。我一直在尝试“kill -INT”,然后是“kill -TERM”,最后是“kill -9”,但前两个从未奏效。 google.com/…【参考方案6】:

在你的终端中找出进程ID(PID):

$ lsof -wni tcp:3000

然后,使用PID列中的数字杀死进程:

$ kill -9 <PID>

【讨论】:

【参考方案7】:

pguardiario 击败了我,尽管他的实现有点危险,因为它使用 SIGKILL 而不是(推荐的)SIGINT。这是我倾向于导入到我的开发项目中的 rake 任务:

lib/tasks/stopserver.rake

desc 'stop server'
task :stopserver do
  pid_file = 'tmp/pids/server.pid'
  if File.file?(pid_file)
    print "Shutting down WEBrick\n"
    pid = File.read(pid_file).to_i
    Process.kill "INT", pid
  end
  File.file?(pid_file) && File.delete(pid_file)
end

当且仅当 pidfile 存在时,才会向服务器发出中断。如果服务器未运行,它不会抛出难看的错误,并且它会通知您它是否实际上正在关闭服务器。

如果您注意到服务器不想使用此任务关闭,请在Process.kill "INT" 行之后添加以下行,并尝试升级到已修复此错误的内核。

Process.kill "CONT", pid

(帽子提示:jackr)

【讨论】:

【参考方案8】:

运行此命令:

locate tmp/pids/server.pid

输出: 此文件的完整路径。如果列表中显示多个文件,请检查您的项目目录名称以找到您关注的文件。

然后运行这个命令:

rm -rf [complete path of tmp/pids/server.pid file]

【讨论】:

单线:x=`locate tmp/pids/server.pid` &amp;&amp; kill `cat $x`【参考方案9】:

Ruby 票证http://bugs.ruby-lang.org/issues/4777 表明这是一个内核 (Linux) 错误。他们提供了一种解决方法(基本上相当于 Ctrl-C/Ctrl-Z 之一),如果您已经妖魔化了服务器,则可以使用:

    杀死 -INT cat tmp/pids/server.pid 杀死 -CONT cat tmp/pids/server.pid

这似乎导致原始 INT 信号被处理,可能允许数据刷新等。

【讨论】:

【参考方案10】:

我在这里留下一个 bash 函数,如果将其粘贴到您的 .bashrc.zshrc 中,您将执行以下操作:

rails start # To start the server in development environment
rails start production # To start the server in production environment
rails stop # To stop the server
rails stop -9 # To stop the server sending -9 kill signal
rails restart # To restart the server in development environment
rails restart production # To restart the server in production environment
rails whatever # Will send the call to original rails command

这里是函数:

function rails() 
  if [ "$1" = "start" ]; then
     if [ "$2" = "" ]; then
        RENV="development"
     else
        RENV="$2"
     fi
     rails server -d -e "$RENV"
     return 0
  elif [ "$1" = "stop" ]; then
     if [ -f tmp/pids/server.pid ]; then
        kill $2 $(cat tmp/pids/server.pid)
        return 0
     else
        echo "It seems there is no server running or you are not in a rails project root directory"
        return 1
     fi
  elif [ "$1" = "restart" ]; then
     rails stop && rails start $2
  else
     command rails $@
  fi;

更多信息在我写的blog post中。

【讨论】:

你有这个等效的批处理文件吗? 不,对不起【参考方案11】:

如果您使用 -d,我认为不会。我会杀掉这个进程。

以后,只需打开另一个终端窗口并使用不带 -d 的命令,它会提供一些非常有用的调试输出。

如果这是生产,请使用乘客或瘦身之类的东西,以便他们轻松停止进程或重新启动服务器

【讨论】:

【参考方案12】: 单行:kill -INT `ps -e | grep 红宝石 | awk '打印 $1'`

ps -e 列出系统上的每个进程 grep ruby 在输出中搜索 ruby​​ 进程 awk 传递该输出的第一个参数 (pid)到kill -INT

如果您只想查看 PID,请尝试使用 echo 而不是 kill。

【讨论】:

【参考方案13】:

如果杀死进程不起作用,那么 从 MyRailsApp/tmp/pids/ 中删除文件 server.pid

【讨论】:

【参考方案14】:

我来这里是因为我试图(未成功)以正常的杀戮方式停止,并认为我做错了什么。

kill -9 是在 Rails 服务器上停止 ruby​​ 的唯一可靠方法吗? 什么!?你知道这意味着什么吗?可能是一场灾难……

【讨论】:

我刚刚因为 kill -9 而丢失了数据。数据还没有刷新到 SQLite,只是在内存中。有趣的事实是,它在记忆中持续了一周。 这是评论,不是这个问题的答案【参考方案15】:

您可以通过将-d 添加到您的命令来在后台启动您的服务器。例如:

puma -d

要停止它,只需终止端口 3000 上正在运行的任何进程:

kill $(cat tmp/pids/server.pid)

【讨论】:

以上是关于如何在 Rails 中停止守护程序服务器?的主要内容,如果未能解决你的问题,请参考以下文章

基于 Spring Boot (Tomcat) 的应用程序作为守护进程 - 如何停止?

如何防止 Spring Boot 守护程序/服务器应用程序立即关闭/关闭?

如何防止 Spring Boot 守护程序/服务器应用程序立即关闭/关闭?

如何停止在端口 3000 上运行 rails 服务器的 nohup 进程

如何守护 Java 程序?

如何编写 Mono 守护程序