如何在Rails中停止Daemon服务器?


75

我正在使用以下命令运行我的Rails应用程序

  $script/server -d webrick 

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

  $kill pid

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

就像rails提供的启动服务器一样,谢谢。

编辑何时合适启动守护程序服务器?任何实时情况都会有所帮助,谢谢

Answers:


32

耙任务怎么样?

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运行


9
kill -9仅在守护程序挂起时使用。否则,您将从Active Directory缓存中丢失未刷新的数据。
Nowaker 2012年

2
可能是这样,但是无论如何,您应该只在开发中运行这样的服务器。
pguardiario 2012年

84

如果有用,在Linux上,您可以找到哪个进程正在使用端口(在这种情况下为3000)可以使用:

lsof -i:3000

它也会返回pid


2
即使在Mac / unix / bash上,是的。这是超级有用的。 lsof -i :3000告诉我正在运行的红宝石的PID
brandonjp 2011年

33
kill $(lsof -i :3000 -t)-该-t选项代表简洁这意味着它将只输出进程ID。
格里

6
很棒 这是我的bash_aliasesalias stopRails='kill -9 $(lsof -i :3000 -t)'使用alias startRails='rails server -d'(如果您不在您的应用程序目录中,它将失败,但是没关系),最后alias restartRails='stopRails && startRails'
Sudhi 2012年

@Sudhi,您的解决方案太棒了
Roman

1
Rubyfied版本:pid = `lsof -i :3000 -t`.chomp.to_i(@ Gerry真的很高兴-t,我今天学到了一些新东西!)
Steve Benner 2014年

36

就像瑞安所说:

您想要的pid在tmp / pids /

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

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


5
lsof -i :3000获得红宝石的PID之后kill -9 1406orWhateverThePIDofRubyWas,-easypeasy-谢谢!
brandonjp 2011年

是的,并且丢失了内存中但尚未在磁盘上的数据。
Nowaker

18

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


7
这里有一个一行,你可以分配给你的〜/ .bashrc文件的别名:kill -9 $(lsof -i:3000) &> /dev/null。后面的部分&>是可选的-仅抑制kill命令的某些输出。
乔什·厄尔

我建议不要运行它,因为自从浏览器与Rails服务器通信以来,其浏览器可能已打开端口3000。这样,我无意中杀死了Chrome。:)
Ryan

18

杀死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/...
jackr


7

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

lib /任务/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

(帽子提示:杰克


6

运行以下命令:

locate tmp/pids/server.pid

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

然后运行以下命令:

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

x=`locate tmp/pids/server.pid` && kill `cat ${x}`
单线

5

一张Ruby票证http://bugs.ruby-lang.org/issues/4777暗示这是一个内核(Linux)错误。它们会变通(基本上等效于Ctrl-C / Ctrl-Z),如果您妖魔了服务器,则可以使用:

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

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


4

在这里,我留下了一个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;
}

我写过的博客文章中提供了更多信息。


您是否有与此等效的批处理文件?
阿米特·乔基

1
不,对不起
等待开发人员...

3

如果您使用-d,我认为它不会。我会杀死这个过程。

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

如果是生产环境,请使用passenger或thin之类的东西,以便他们很容易停止进程或重新启动服务器


3
单线:kill -INT`ps -e | grep红宝石| awk'{print $ 1}'`

ps -e列出系统
grep ruby搜索的每个进程,其中 针对ruby进程的输出将该输出
awk的第一个参数(pid)传递给kill -INT


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


2

如果终止进程不起作用,则从MyRailsApp / tmp / pids /中删除文件server.pid


1

我来这里是因为我试图(不成功地)以正常的杀伤力停止,并认为我做错了什么。

Kill -9是在Rails服务器上停止红宝石的唯一确定方法吗?什么!?您知道这意味着什么吗?可能是一场灾难...


我只是失去了,因为杀的数据-9。数据尚未刷新到SQLite,仅在内存中。有趣的是,它在内存中保存了一个星期。
Nowaker

这是评论,不是对这个问题的答案
Raheel

1

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

puma -d

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

kill $(cat tmp/pids/server.pid)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.