Выполнение длинной задачи на удаленном сервере с помощью python-rq
Я написал код, выполнение которого занимает много времени (2-3 дня), и я хочу отправить его на сервер, который будет выполняться там. Код богат классами и функциями, взаимодействующими друг с другом, но в конце концов выполнение всего кода выполняется с помощью одной функции (test2), которая заставит его работать. Я обнаружил, что решением для меня может быть очередь задач, и, поскольку мне не нужно выполнять несколько задач одновременно, я обнаружил, что RQ может удовлетворить мои потребности.
#action_test.py
import action2
def test1():
fl = action2.FollowersList()
mech = action2.Mechanics()
manager = action2.Manager()
manager.launch(mech,fl)
for i in range(0,10):
manager.iterate(mech,fl)
def test2():
messageList = []
fl = action2.FollowersList()
mech = action2.Mechanics()
manager = action2.Manager()
manager.launch(mech,fl)
for i in range(0,2000):
message = manager.iterate(mech,fl)
messageList.append(message)
return messageList
Я настроил Reddis на удаленном сервере. Запустите его в режиме демона. Затем я написал простой модуль, который должен просто поставить мою функцию test2 в очередь.
#app.py
from rq import Connection, Queue
from redis import Redis
from action_test import test2
def main():
# Tell RQ what Redis connection to use
redis_conn = Redis()
q = Queue(connection=redis_conn) # no args implies the default queue
# Delay calculation of the multiplication
job = q.enqueue(test2, timeout = 259200)
print job.result # => None
if __name__ == '__main__':
main()
Затем я столкнулся с проблемой: на веб-странице документации по python-rq ( http://python-rq.org/docs/workers/) описанный способ запуска работника - выполнить
$ rqworker
из скорлупы Но этот рабочий запускается не как демон, и поэтому, когда я подключаюсь к этому удаленному серверу, где мое приложение настроено по ssh, если мое ssh-соединение прерывается, рабочий тоже отключается, и это не совсем то поведение, которое мне бы хотелось иметь. Поддержание соединения ssh в течение 2-3 дней во время выполнения моего кода отрицает всю логику, кроме использования python-rq в моем случае. Есть ли способы обойти эту проблему? Возможно, рабочий python-rq должен быть запущен не из оболочки, которую нужно демонизировать?
3 ответа
Вы можете запустить работника в фоновом режиме (&
) и отправить вывод в текстовый файл (nohup
):
nohup rqworker &
По умолчанию это запишет вывод в файл nohup.out
в том же каталоге (или $HOME/nohup.out
если это не разрешено). Теперь вы можете закрыть соединение ssh.
При настройках по умолчанию rq будет много писать в этом файле, но --quiet
помогает:
nohup rqworker --quiet &
Смотрите man nohup и как начать работу в фоновом режиме.
Насколько я могу сказать, вам не нужно python-rq
совсем. Очередь сообщений обычно используется для связи в распределенной системе, что является слишком сложным для человека, который просто хочет запустить долго выполняющийся скрипт на удаленном сервере. Вы могли бы пропустить rqworker
и запустите ваш скрипт напрямую. добавлять if __name__=='__main__': test2()
на ваш action_test.py
скрипт, тогда вы можете запустить скрипт из командной строки:
python test_action.py
Как вы указали, когда вы закрываете сеанс SSH, ваш скрипт также уничтожается. Это происходит из-за магии Unix/Linux, называемой "сигналы": система отправляет сигнал "зависания" на вашу работу, также известный как SIGHUP
, Мартин упомянул nohup
уже и это работоспособный ответ (например, nohup python test_action.py
) но это немного сложно для новичка, который просто хочет запустить длинный скрипт.
Более простым решением для вас является использование screen
, Screen создает виртуальный терминал, который позволяет вам отключиться от оболочки и подключиться позже. Если у вас установлен экран, просто запустите screen
и он создаст новый виртуальный терминал для вас. Теперь запустите вашу программу как обычно: python test_action.py
, Как только это начнется, нажмите Ctrl+A, а затем D, чтобы отключиться. Теперь вы можете отключить сеанс SSH, но работа будет продолжаться в виртуальном терминале, как будто ничего не произошло. Позже вы можете вернуться по SSH на сервер и набрать screen -r
возобновить использование этого терминала.
Более подробная информация здесь: https://unix.stackexchange.com/questions/24658/nohup-vs-screen
Вы можете использовать пакет http://supervisord.org/ для этого. Это помогает настроить процесс deamon для запуска задачи в фоновом режиме. И это также довольно легко настроить.