4

今天我收到了一封来自 Celery 的错误电子邮件,有人可以解释一下吗?可能我该如何解决超时问题?这将非常有帮助,谢谢。

PS 尽管有这个错误,我的消息似乎已经发送,这也是正确的吗?

错误:

Task Request to Process with id 65123935-b190-4718-9ed0-fb863359f27f 
 raised exception:
'TimeLimitExceeded(300.0,)'


Task was called with args: (<Batch: Batch object>,) kwargs: {}.

The contents of the full traceback was:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/billiard/pool.py", line 496, in on_hard_timeout
    raise TimeLimitExceeded(job._timeout)
TimeLimitExceeded: TimeLimitExceeded(300.0,)


--
Just to let you know,
py-celery at w1.ip-10-32-53-113.

任务:

class ProcessRequests(Task):
    name = "Request to Process"
    max_retries = 1
    default_retry_delay = 3

    def run(self, batch):
        # Only run this task on non-scheduled tasks
        if batch.status != "Scheduled":
            q = Contact.objects.filter(contact_owner=batch.user)
            if batch.group == None:
                q = q.filter(id=batch.contact_id)
            else:
                q = q.filter(group=batch.group)

            for e in q:
                msg = Message.objects.create(
                    recipient_number=e.mobile,
                    content=batch.content,
                    sender=e.contact_owner,
                    billee=batch.user,
                    sender_name=batch.sender_name
                )
                gateway = Gateway.objects.get(pk=2)
                msg.send(gateway)
4

4 回答 4

2

您收到 TimeLimitExceeded 异常,因为您的任务执行时间超过 300 秒。300 秒是任务可以运行的默认时间。

正如 Avichal Badaya 所回答的那样,您可以配置 Celery 以允许执行更长时间的任务。

您提到您的消息仍在发送,但这可能会发生,因为您的任务是为批处理编写的。因此,您要么尝试发送多条消息,要么只尝试发送一条消息,但有些消息会弄乱批次。

你能告诉我们你怎么称呼这个任务吗?

于 2013-06-26T08:31:54.653 回答
1

You are sending messages to mobile phones with msg.send(gateway), right?

Inside this method, you are connecting to remote webservice, which actually sends the message, right?

Then, your message might have been sent, but your connection to remote party hasn't been closed, despite webservice should have closed it, after sending message and a response for your request.

The last thing - you haven't done the following before creating socket used to connect with webservice:

import socket
socket.setdefaulttimeout(seconds) # seconds argument is of type float

This way, your task is hanging at the socket for infinite time waiting for webservice to send response and/or close the connection. In fact it would wait forever, if not interrupted by celery timeout.

Default socket timeout value is None as the documentation states http://docs.python.org/2/library/socket.html#socket.setdefaulttimeout

Hope this is helpful.

于 2013-06-27T13:50:45.457 回答
1

首先,当您收到有关任务功能/方法的消息时,您必须知道自己在做什么,以及它的时间复杂度。如果您的任务需要超过默认的 300 秒才能完成,那么 celery 主进程将首先发送SoftTimeLimitExceed异常,如果我们将其包含在 try/except 块中,您可以捕获您的任务。此异常实际上是用于清理过程(如果有)。在此异常之后,芹菜将向您发送另一个异常TimeLimitExceed异常,它将杀死您的工作线程。

如果您在 celery 设置上启用了延迟 ACK 设置,那么相同的消息将被传递给另一个工作人员进行处理(这很危险,因为这也会失败)。

因此,如果您遇到此异常,则意味着您的任务需要超过 300 秒才能完成,因此请调整 celery 设置中工作人员的最大时间限制以满足您的要求。

问候,

哈里达斯·N。

于 2013-06-26T04:59:18.280 回答
1

您可以尝试修改 celeryd 设置吗?文件应该主要是 /etc/init.d/celeryd 。

CELERYD_OPTS="--time-limit==3600 -E --loglevel=DEBUG"
于 2013-06-21T19:39:40.317 回答