Wie stoppe ich einen Daemon Server in Rails?

75

Ich führe meine Rails-Anwendung wie folgt aus

  $script/server -d webrick 

Führen Sie auf meinem Ubuntu-System mit dem obigen Befehl den Webrick-Server im Hintergrund aus. Ich könnte den Prozess mit dem Befehl kill beenden

  $kill pid

Bietet Rails einen Befehl zum Stoppen des Hintergrunds, auf dem der Daemon-Server ausgeführt wird?

Wie die, die von Rails zum Starten des Servers bereitgestellt wird. Danke.

BEARBEITEN Wann ist es angebracht, den Daemon-Server zu starten? Jedes Echtzeitszenario hilft Danke

Srinivas MV
quelle

Antworten:

32

Wie wäre es mit einer Rechenaufgabe?

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

Laufen Sie mit Rake Stop oder Sudo Rake Stop

pguardiario
quelle
9
Verwenden Sie kill -9nur dann , wenn der Dämon hing. Andernfalls verlieren Sie Ihre nicht gelöschten Daten aus Active Directory-Caches.
Nowaker
2
Das mag sein, aber Sie sollten sowieso nur einen solchen Server in der Entwicklung betreiben.
pguardiario
84

Wenn es nützlich sein kann, können Sie unter Linux herausfinden, welcher Prozess einen Port verwendet (in diesem Fall 3000), den Sie verwenden können:

lsof -i: 3000

es wird auch die PID zurückgeben

Magnum
quelle
2
Sogar auf Mac / Unix / Bash ... Ja. Das ist super hilfreich. lsof -i :3000sagt mir die PID des laufenden Rubins
brandonjp
33
kill $(lsof -i :3000 -t)- Die Option -t steht für knapp, was bedeutet, dass nur die Prozess-ID ausgegeben wird.
Gerry
6
genial; Hier sind meine bash_aliases alias stopRails='kill -9 $(lsof -i :3000 -t)'mit alias startRails='rails server -d'(wird fehlschlagen, wenn Sie nicht in Ihrem App-Verzeichnis sind, aber das ist in Ordnung) und schließlichalias restartRails='stopRails && startRails'
Sudhi
@ Sudhi, Ihre Lösung ist total genial
Roman
1
Rubyfied Version: pid = `lsof -i :3000 -t`.chomp.to_i(@Gerry wirklich netter Anruf auf der -tFlagge, ich habe heute etwas Neues gelernt!)
Steve Benner
36

Wie Ryan sagte:

Die gewünschte PID ist in tmp / pids /

wahrscheinlich ist server.pid die gewünschte Datei.

Sie sollten in der Lage sein, kill -9 $(cat tmp/pids/server.pid)einen daemonisierten Server herunterzufahren.

Douglas Meyer
quelle
5
Nachdem lsof -i :3000ich die PID von Rubin erhalten habe, dann kill -9 1406orWhateverThePIDofRubyWas- easypeasy - Danke!
Brandonjp
Ja, und verlieren Sie die Daten, die sich im Speicher und noch nicht auf der Festplatte befinden.
Nowaker
18

Die Prozess-ID des Daemon-Servers wird in Ihrem Anwendungsverzeichnis tmp / pids / gespeichert. Sie können Ihren Standard kill process_idmit den Informationen verwenden, die Sie dort finden.

Ryan
quelle
7
Hier ist ein Einzeiler, den Sie einem Alias ​​in Ihrer ~ / .bashrc-Datei zuweisen können : kill -9 $(lsof -i:3000) &> /dev/null. Der &>nachfolgende Teil ist optional - er unterdrückt nur einige Ausgaben des Befehls kill.
Josh Earl
Ich würde empfehlen, dies nicht auszuführen, da in Ihrem Browser möglicherweise Port 3000 geöffnet ist, da er mit Ihrem Rails-Server kommuniziert. Ich habe Chrome versehentlich ein paar Mal auf diese Weise getötet. :)
Ryan
18

Der einzig richtige Weg, um den Ruby on Rails-Standardserver (WEBrick) zu beenden, ist:

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

Wenn Sie Mongrel ausführen, ist dies ausreichend:

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

Verwenden kill -9Sie diese Option, wenn Ihr Daemon hängt. Denken Sie an die Auswirkungen von kill -9: Wenn die in Active Record-Caches gespeicherten Daten nicht auf die Festplatte geschrieben wurden, gehen Ihre Daten verloren. (Wie ich es kürzlich getan habe)

Nowaker
quelle
Hmmm… aber wie in einem anderen Artikel erwähnt, scheinen Rails oder WEBrick oder jemand alle sanfteren Signale zu ignorieren. Ich habe versucht "kill -INT", dann "kill -TERM" und schließlich "kill -9", aber die ersten beiden funktionieren nie. google.com/…
jackr
16

In Ihrem Terminal, um die Prozess-ID (PID) herauszufinden:

$ lsof -wni tcp:3000

Verwenden Sie dann die Nummer in der PID-Spalte, um den Prozess abzubrechen:

$ kill -9 <PID>
Ramiz Raja
quelle
7

pguardiario hat mich geschlagen, obwohl seine Implementierung ein bisschen gefährlich ist, da sie SIGKILLanstelle der (empfohlenen) verwendet SIGINT. Hier ist eine Rechenaufgabe, die ich in meine Entwicklungsprojekte importiere:

lib / task / 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

Dies führt nur dann zu einer Unterbrechung des Servers, wenn die PID-Datei vorhanden ist. Es werden keine unschönen Fehler ausgegeben, wenn der Server nicht ausgeführt wird, und es benachrichtigt Sie, wenn der Server tatsächlich heruntergefahren wird.

Wenn Sie feststellen, dass der Server mit dieser Aufgabe nicht heruntergefahren werden soll, fügen Sie nach der Process.kill "INT"Zeile die folgende Zeile hinzu und versuchen Sie, ein Upgrade auf einen Kernel durchzuführen, bei dem dieser Fehler behoben ist.

Process.kill "CONT", pid

( Hutspitze : Jackr )

Justin ᚅᚔᚈᚄᚒᚔ
quelle
6

Führen Sie diesen Befehl aus:

locate tmp/pids/server.pid

Ausgabe: Vollständiger Pfad dieser Datei. Überprüfen Sie den Namen Ihres Projektverzeichnisses, um Ihre betroffene Datei zu finden, wenn mehrere Dateien in der Liste angezeigt werden.

Führen Sie dann diesen Befehl aus:

rm -rf [complete path of tmp/pids/server.pid file]
Taimoor Changaiz
quelle
x=`locate tmp/pids/server.pid` && kill `cat ${x}`
Einzeiler
5

Ein Ruby-Ticket, http://bugs.ruby-lang.org/issues/4777 , deutet darauf hin, dass es sich um einen Kernel-Fehler (Linux) handelt. Sie bieten eine Problemumgehung (im Wesentlichen gleichbedeutend mit Strg-C / Strg-Z), die Sie verwenden können, wenn Sie den Server verteufelt haben:

  1. töte -INT cat tmp/pids/server.pid
  2. töten -CONT cat tmp/pids/server.pid

Dies scheint dazu zu führen, dass das ursprüngliche INT-Signal verarbeitet wird, was möglicherweise ein Löschen der Daten usw. ermöglicht.

jackr
quelle
4

Hier hinterlasse ich eine Bash-Funktion, die, wenn sie in Sie eingefügt wird .bashrcoder .zshrclegiert, Dinge wie:

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

Hier ist es die Funktion:

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;
}

Weitere Informationen in dem Blog-Beitrag, den ich darüber geschrieben habe.

Warten auf Dev ...
quelle
Haben Sie eine entsprechende Batch-Datei dafür?
Amit Joki
1
Nein, es tut mir leid
Warten auf Dev ...
3

Ich glaube nicht, dass es funktioniert, wenn Sie -d verwenden. Ich würde den Prozess einfach beenden.

Öffnen Sie in Zukunft stattdessen einfach ein anderes Terminalfenster und verwenden Sie den Befehl ohne -d. Er bietet einige wirklich nützliche Debugging-Ausgaben.

Wenn es sich um eine Produktion handelt, verwenden Sie beispielsweise Passagier oder Thin, damit die Prozesse leicht gestoppt oder die Server neu gestartet werden können


quelle
3
Einzeiler: kill -INT `ps -e | grep rubin | awk '{print $ 1}' `

ps -elistet jeden Prozess auf dem System auf, der
grep rubysucht, dass die Ausgabe für den Ruby-Prozess
awkdas erste Argument dieser Ausgabe (die PID) an übergibt kill -INT.


Versuchen Sie es mit Echo statt Kill, wenn Sie nur die PID sehen möchten.

Billrichards
quelle
2

Wenn der Kill-Prozess nicht funktioniert, löschen Sie die Datei server.pid aus MyRailsApp / tmp / pids /

SunTechnique
quelle
1

Ich bin hierher gekommen, weil ich (erfolglos) versucht habe, mit einem normalen Kill aufzuhören, und dachte, ich würde etwas falsch machen.

Ein Kill -9 ist der einzig sichere Weg, um einen Ruby on Rails-Server zu stoppen? Was!? Kennen Sie die Auswirkungen davon? Kann eine Katastrophe sein ...

FrameGrace
quelle
Ich habe gerade die Daten wegen kill -9 verloren. Die Daten wurden noch nicht in SQLite gelöscht, sondern nur im Speicher. Interessanterweise war es eine Woche lang in Erinnerung.
Nowaker
Dies ist ein Kommentar, keine Antwort auf diese Frage
Raheel
1

Sie können Ihren Server im Hintergrund starten, indem Sie ihn -dzu Ihrem Befehl hinzufügen . Zum Beispiel:

puma -d

Um es zu stoppen, beenden Sie einfach den Prozess, der auf Port 3000 ausgeführt wird:

kill $(cat tmp/pids/server.pid)
Flavio Wuensche
quelle