Як зупинити Daemon Server у Rails?


75

Я запускаю свою програму rails, використовуючи наступне

  $script/server -d webrick 

в моїй системі Ubuntu вище команди запустіть сервер webrick у фоновому режимі. Я міг би вбити процес за допомогою команди kill

  $kill pid

Чи надає rails якусь команду, щоб зупинити фоновий сервер демона?

на зразок того, який надає rails для запуску сервера, дякую.

РЕДАГУВАТИ Коли доречно запустити сервер демона? Будь-який сценарій реального часу допоможе спасибі

Відповіді:


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

біг із зупинкою граблів або зупинкою граблів судо


9
Використовуйте kill -9лише тоді, коли демон завис. В іншому випадку ви втратите свої нечищені дані з кеш-пам’яті Active Directory.
Nowaker

2
Це може бути, але ви все одно повинні запускати лише такий сервер у розробці.
pguardiario

84

якщо це може бути корисним, в Linux ви можете знайти, який процес використовує порт (у цьому випадку 3000), ви можете використовувати:

lsof -i: 3000

він також поверне pid


2
Навіть на Mac / unix / bash ... Так. Це дуже корисно. lsof -i :3000повідомляє мені ПІД запущеного рубіна
brandonjp

33
kill $(lsof -i :3000 -t)- Параметр -t розшифровується як terse, що означає, що він просто виведе ідентифікатор процесу.
Gerry

6
дивовижний; ось мої bash_aliases alias stopRails='kill -9 $(lsof -i :3000 -t)'з alias startRails='rails server -d'(не вдасться, якщо вас немає в каталозі вашої програми, але це нормально) і нарештіalias restartRails='stopRails && startRails'
Судхі

@Sudhi, ваше рішення надзвичайно чудове
Роман

1
Рубіфікована версія: pid = `lsof -i :3000 -t`.chomp.to_i(@Gerry дійсно гарний заклик до -tпрапора, я сьогодні дізнався щось нове!)
Стів Беннер

36

Як сказав Райан:

потрібний вам pid знаходиться в tmp / pids /

ймовірно server.pid - це потрібний файл.

Ви повинні мати змогу запустити kill -9 $(cat tmp/pids/server.pid)демонізований сервер.


5
Після того, як lsof -i :3000я отримаю PID рубіну, тоді kill -9 1406orWhateverThePIDofRubyWas- дуже просто - Дякую!
brandonjp

Так, і втратити дані, які є в пам’яті, а ще не на диску.
Новекер

18

Ідентифікатор процесу сервера-демона зберігається у каталозі вашого додатка tmp / pids /. Ви можете використовувати свій стандарт kill process_idз інформацією, яку ви там знайдете.


7
Ось один вкладиш , який можна призначити назву в вашому файлі ~ / .bashrc: kill -9 $(lsof -i:3000) &> /dev/null. Частина після &>є необов’язковою - вона просто придушує певний результат від команди kill.
Джош Ерл

Я б не рекомендував запускати це, оскільки у вашому браузері може бути відкритий порт 3000, оскільки він розмовляє з вашим сервером Rails. Я випадково вбив Chrome кілька разів таким чином. :)
Райан

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

16

У вашому терміналі, щоб дізнатись ідентифікатор процесу (PID):

$ lsof -wni tcp:3000

Потім використовуйте номер у стовпці PID, щоб перебити процес:

$ kill -9 <PID>

7

pguardiario побив мене, хоча його реалізація трохи небезпечна, оскільки використовує SIGKILLзамість (рекомендований) SIGINT. Ось завдання граблі, яке я схильний імпортувати у свої проекти розвитку:

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

Це видає переривання сервера тоді і тільки тоді, коли файл pid існує. Він не видає непривабливих помилок, якщо сервер не працює, і повідомляє, чи насправді він вимикає сервер.

Якщо ви помітили, що сервер не хоче закриватися за допомогою цього завдання, додайте наступний рядок після 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. kill -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;
}

Більше інформації в блозі я писав про це.


у вас є еквівалентний пакетний файл для цього?
Amit Joki

1
Ні, вибачте
Чекаю Dev ...

3

я не думаю, що це так, якщо ви використовуєте -d. Я б просто вбив процес.

Надалі просто відкрийте інше вікно терміналу і скористайтеся командою без -d, це забезпечить справді корисний результат налагодження.

Якщо це виробництво, використовуйте щось на зразок пасажирське або тонке, щоб було легко зупинити процеси або перезапустити сервери


3
однокласний: kill -INT `ps -e | grep ruby ​​| awk '{print $ 1}' '

ps -eперераховує кожен процес у системі, який
grep rubyшукає, що вихід для рубінового процесу
awkпередає перший аргумент цього результату (pid) до kill -INT.


Спробуйте за допомогою луни, а не вбивання, якщо ви просто хочете побачити PID.


2

якщо процес вбивства не працює, видаліть файл server.pid з MyRailsApp / tmp / pids /


1

Я прийшов сюди, тому що намагався (невдало) зупинитися звичайним вбивством і думав, що роблю щось не так.

Вбивство -9 - єдиний надійний спосіб зупинити рубін на рейковому сервері? Що!? Чи знаєте ви наслідки цього? Може бути катастрофою ...


Я просто втратив дані через kill -9. Дані ще не були видалені в SQLite, лише в пам’яті. Цікавий факт, це було в пам'яті тиждень.
Новекер

це коментар, а не відповідь на це питання
Рахіл

1

Ви можете запустити свій сервер у фоновому режимі, додавши -dдо своєї команди. Наприклад:

puma -d

Щоб зупинити це, просто вбийте будь-який процес, що працює на порту 3000:

kill $(cat tmp/pids/server.pid)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.