优先级队列不与Celery和RabbitMQ一起使用

时间:2017-10-10 07:31:35

标签: python rabbitmq celery background-process

我试图在我的烧瓶应用中使用 Celery 3.1.23 RabbitMQ 3.6.11 的优先级队列。但是工作人员不会根据优先级来完成任务。这是我的代码:

芹菜配置:

CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', RABBITMQ_URL)
CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', REDIS_URL)
BROKER_POOL_LIMIT = int(os.environ.get('BROKER_POOL_LIMIT', 10))
CELERY_DEFAULT_QUEUE = 'non_web'
CELERY_IGNORE_RESULT = True
CELERY_ACKS_LATE = True
CELERY_SEND_EVENTS = False
CELERY_TASK_RESULT_EXPIRES = 3600
CELERY_RESULT_PERSISTENT = False

CELERY_TASK_QUEUES = (
    Queue('urgent', Exchange('urgent', type='direct'), routing_key='urgent', queue_arguments={'x-max-priority': 8}),
    Queue('web', Exchange('web', type='direct'), routing_key='web', queue_arguments={'x-max-priority': 6}),
    Queue('non_web', Exchange('non_web', type='direct'), routing_key='non_web', queue_arguments={'x-max-priority': 4}),
    Queue('background', Exchange('background', type='direct'), routing_key='background', queue_arguments={'x-max-priority': 2}),
)

在这里,我希望在urgent队列中排队的任务获得更高的优先级。然后是web,然后是non_web,最后是background个队列。但是non-web中排队的任务总是先执行。这是工作的代码。

工作:

from time import sleep

@celery.task(queue='web', priority=8)
def high_priority_job():
    print 'High priority job'
    for i in range(1, 31):
        print i
        sleep(1)

@celery.task(queue='non_web', priority=6)
def medium_priority_job():
    print 'Medium priority job'
    for i in range(1, 31):
        print i
        sleep(1)

我尝试在这样的队列中排队作业:

def queue_jobs():
    for i in range(50):
        medium_priority_job.delay()
    for i in range(20):
        high_priority_job.delay()

在此过程中,只有在完成所有中优先级作业后才执行高优先级作业。我也尝试从作业声明中删除优先级,并在排队作业时设置它:

def queue_jobs():
    for i in range(50):
        medium_priority_job.apply_async(priority=6)
    for i in range(20):
        high_priority_job.apply_async(priority=8)

这也没有用。我尝试将Celery升级到最新版本。这也没有帮助。这有什么不对?我需要更改任何设置吗?

2 个答案:

答案 0 :(得分:0)

请注意,优先级值是以相反的顺序排序的:0是根据celery官方文档的最高优先级。 https://docs.celeryproject.org/en/v4.3.0/userguide/routing.html

在您的情况下,medium_priority_job将首先执行,因为优先级是6,然后执行下一个high_priority_job,这是正确的。

答案 1 :(得分:0)

难怪考虑到每种情况下您使用不同的队列都行不通,因此它们会定期执行。因此,要测试优先级使用情况,请使用单个队列,然后向其发送具有不同优先级的任务。

此外,关于优先级及其使用不同经纪人时的含义,还有一些困惑-link