python imaplib 使用 celeryd 队列时的 SSL 错误

2 投票
3 回答
1289 浏览
提问于 2025-04-15 17:42

我在使用 Python 2.6 的 imaplib 库和最新的 Django 版本时遇到了问题。我想通过队列(使用 celeryd)下载 IMAP 邮件。我可以在命令行中连接并下载邮件,但当我通过 Django 将任务交给 celeryd 时,就出现了这个错误:“SSLError: [Errno 1] _ssl.c:1325: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number”。

imaplib 的文档没有提到如何指定 SSL 的版本。我想从 Gmail 拉取邮件,但我不明白为什么将任务交给队列使用 celeryd 会导致任务失败。任何帮助都会非常感激。

编辑:这里是一个错误追踪信息:

文件 "/usr/lib/python2.6/imaplib.py",第 643 行,在 select 中 typ, dat = self._simple_command(name, mailbox)

文件 "/usr/lib/python2.6/imaplib.py",第 1059 行,在 _simple_command 中 return self._command_complete(name, self._command(name, *args))

文件 "/usr/lib/python2.6/imaplib.py",第 889 行,在 _command_complete 中 typ, data = self._get_tagged_response(tag)

文件 "/usr/lib/python2.6/imaplib.py",第 990 行,在 _get_tagged_response 中 self._get_response()

文件 "/usr/lib/python2.6/imaplib.py",第 907 行,在 _get_response 中 resp = self._get_line()

文件 "/usr/lib/python2.6/imaplib.py",第 1000 行,在 _get_line 中 line = self.readline()

文件 "/usr/lib/python2.6/imaplib.py",第 1170 行,在 readline 中 char = self.sslobj.read(1)

文件 "/usr/lib/python2.6/ssl.py",第 136 行,在 read 中 return self._sslobj.read(len)

SSLError: [Errno 1] _ssl.c:1325: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

编辑:这是我尝试运行的任务,其中 imap_parser 是一个封装了 imaplib 的模块,用于将邮件加载到我的数据库中。

class DumpIMAPData(Task):
    def run(self, user, username, password, imap_address, **kwargs):
        logger = self.get_logger(**kwargs)
        celery.log.redirect_stdouts_to_logger(logger, loglevel=None)
        #imap_address is e.g. 'imap.gmail.com'                                  
        parser = imap_parser.IMAPFetcher(imap_address, username, password, user\
)
        parser.load_all_emails()
    return True

我注意到这个任务实际上会在使用 celery 时运行,除非我使用 --detach 标志将任务变为守护进程。我不知道为什么任务只有在作为守护进程运行时才会失败。我尝试使用 -u 和 -g 标志设置相同的用户 ID 和组 ID,设置相同的 umask,并确保守护进程和非守护进程的路径和工作目录相同,但当 celery 作为守护进程运行时,任务仍然无法在 celery 中运行。

我正在使用最新版本的 celery(0.9.4)。

3 个回答

0

你正在连接一个不支持TLS的端口。你是想和一个支持TLS/SSL的邮件服务器通信,还是说celery在尝试为它的AMQP连接使用TLS呢?

1

如果这个问题只在celery工作进程里出现,那可能是和amqplib有关(它使用了ssl模块),或者是和多进程和分叉有关(比如在分叉之前初始化的全局变量现在不再有效了)。

你能不能告诉我你正在尝试运行的任务是什么?你是在任务内部连接服务器,还是用某种共享对象?

1

根据celeryd的创始人说:

从版本01a8a0e开始,Celery不再自己处理分离(也就是在后台运行)这个功能了。之前这个功能出现了太多问题,所以现在建议大家使用其他工具,比如start-stop-daemon、supervisord、launchd等等,来实现这个功能。

撰写回答