使用python-rq在远程服务器上执行长任务

时间:2014-05-04 21:16:08

标签: python redis flask 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 docs网页(http://python-rq.org/docs/workers/)上,所描述的启动工作者的方法是执行

$ rqworker
来自shell的

但是这个工作者不是作为一个守护进程启动的,因此我连接到这个远程服务器,我的应用程序通过ssh设置,如果我的ssh连接断开,工作人员也会关闭,这不是我想要的行为具有。在我的代码执行时维护ssh连接2-3天,在我的情况下拒绝使用python-rq的整个逻辑。有没有解决这个问题的方法?也许一个python-rq worker应该不是从shell启动来守护进程的?

3 个答案:

答案 0 :(得分:1)

您可以在后台运行worker(&)并将输出发送到文本文件(nohup):

nohup rqworker &

默认情况下,这会将输出写入同一目录中的文件nohup.out(如果不允许,则为$HOME/nohup.out)。您现在可以关闭ssh连接。

使用默认设置,rq会在此文件中写很多内容,--quiet有助于:

nohup rqworker --quiet &

请参阅man nohuphow to start jobs in background

答案 1 :(得分:1)

据我所知,你根本不需要python-rq。消息队列通常用于分布式系统中的通信,这对于想要在远程服务器上运行长时间运行的脚本的人来说是过度的。您可以跳过rqworker并直接运行脚本。将if __name__=='__main__': test2()添加到action_test.py脚本,然后您可以从命令行运行脚本:

python test_action.py

正如您所指出的,当您关闭SSH会话时,您的脚本也会被杀死。这是因为一些叫做“信号”的Unix / Linux魔术:系统向你的工作发送一个“挂起”信号,也称为SIGHUP。 Martin已经提到nohup,这是一个可行的答案(例如nohup python test_action.py),但对于想要运行长脚本的初学者来说,这有点复杂。

更简单的解决方案是使用screen。屏幕创建一个虚拟终端,允许您从shell断开连接并稍后重新连接。如果您安装了屏幕,只需运行screen,它就会为您创建一个新的虚拟终端。现在正常运行您的程序:python test_action.py。一旦开始,键入 Ctrl + A 然后 D 断开连接。现在您可以断开SSH会话,但作业将继续在虚拟终端中运行,就好像什么都没发生一样。稍后,您可以通过SSH回到服务器并键入screen -r以继续使用该终端。

此处有更多信息:https://unix.stackexchange.com/questions/24658/nohup-vs-screen

答案 2 :(得分:0)

您可以使用supervisord包。它有助于设置一个在后台运行任务的deamon进程。它也很容易配置。