0

我已经编写了一些需要很长时间才能执行(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 之外的整个逻辑。有没有办法解决这个问题?也许不应该从 shell 启动一个 python-rq worker 来进行守护进程?

4

3 回答 3

1

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

nohup rqworker &

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

使用默认设置,rq 将向该文件写入很多内容,但会有所--quiet帮助:

nohup rqworker --quiet &

请参阅man nohup以及如何在后台开始工作

于 2014-05-04T21:32:54.840 回答
1

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

python test_action.py

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

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

更多信息在这里:https ://unix.stackexchange.com/questions/24658/nohup-vs-screen

于 2015-08-30T15:16:57.403 回答
0

您可以为此使用supervisord包。它有助于为在后台运行任务设置一个守护进程。而且它也很容易配置。

于 2016-05-04T13:36:53.897 回答