Celery + RabbitMQ +“发生套接字错误”

Posted

技术标签:

【中文标题】Celery + RabbitMQ +“发生套接字错误”【英文标题】:Celery + RabbitMQ + "A socket error ocurred" 【发布时间】:2014-12-23 07:59:12 【问题描述】:

我在 Django 中使用 Celery,并将 RabbitMQ 作为 Heroku 上的代理。我的 RabbitMQ 服务是 Heroku 上的 CloudAMQP Tough。如果相关的话,我们一直在尝试解决一些频繁的内存泄漏,但通常情况下服务不会降级。

当网站访问量很大时(比如今天),我开始偶尔遇到如下错误:

Couldn't log in: a socket error occurred

任务被完全抛出并且没有在任何地方注册。这显然是一个业务关键问题。我的芹菜设置如下:

BROKER_URL = os.getenv('CLOUDAMQP_URL', DEFAULT_AMQP)
CELERY_TASK_SERIALIZER = 'pickle'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['pickle', 'json']
CELERY_ENABLE_UTC = True
# CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend']
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True
CELERY_SEND_TASK_ERROR_EMAILS = True
CELERY_RESULT_BACKEND = False
CELERY_IMPORTS = ('business.admin', 'mainsite.views', 'utils.crons', 'mainsite.forms', )
BROKER_POOL_LIMIT = 5

# trying to clean up this memory leak
CELERYD_MAX_TASKS_PER_CHILD = 5
CELERYD_TASK_TIME_LIMIT = 60*60

我对 celery 有点陌生,所以我很乐意提供任何有用的日志/等作为后续跟进,但我什至不确定此时要提供什么。在我的设置或环境中是否有任何明显的东西似乎在大量流量时可能导致此问题?

【问题讨论】:

可能你的文件描述符用完了? 【参考方案1】:

Socket 错误可能是由于 Linux Out-of-Memory Killer 杀死了 RabbitMQ 或 Heroku。当服务器由于某些进程没有使用内存分配而耗尽内存时,Linux内核会尝试查找原因并杀死相关进程。 RabbitMQ 使用过多内存可能会导致被杀死。 你可以使用grep -i kill /var/log/messages*查看Linux OOM是否杀死了一个特定的进程

使用以下链接了解更多详情和了解 Linux OOM 配置:

How to Configure the Linux Out-of-Memory Killer

你使用supervisord吗?

Supervisord 是一个用于运行和监控进程的漂亮守护进程。使用这个,您可以确保所有长时间运行的进程(例如 RabbitMQ)始终处于启动和运行状态,即使进程被终止也是如此。

内存泄漏有两种可能的原因:

    如果 settings.DEBUG 为 True,这可能会导致内存泄漏。确保在您的工作人员配置中将 settings.DEBUG if 设置为 False。

    如果您打算保留任务结果,则应该使用它们。如果您不使用它们,您将面临内存泄漏问题。要解决此问题,您可以使用以下几行更改设置:

    # Just ignore the results, in case you're not consuming results.
    CELERY_IGNORE_RESULT = True
    CELERY_STORE_ERRORS_EVEN_IF_IGNORED = False
    

【讨论】:

以上是关于Celery + RabbitMQ +“发生套接字错误”的主要内容,如果未能解决你的问题,请参考以下文章

libevent 如何检测到套接字已关闭

socket.io 由于数据大小而断开连接

不能让 Xdebug 工作超过 5 分钟。发生超时