使用Celery和RabbitMQ的Python Web API失控队列时间

2024-06-17 12:00:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我用nginx和uWSGI构建了一个基于python的web API,它可以处理大约100-200rps(每秒的请求),响应时间为100-300ms。当收到API请求时,应用程序通过geventHTTPclient触发对其他数据源的一个或多个后端API调用,然后聚合数据以响应初始请求。在

在最近的代码升级中,我将这些后端API调用卸载到Celery(使用libRabbitMQ作为代理)。当我将这段代码发布到生产环境中时,结果最初是可以接受的——由于来自2个以上数据源的外部延迟,平均响应时间略有增加,但应用程序开销时间大致相同。然而,随着时间的推移,我注意到我的API的延迟严重降低,高达初始延迟的10倍,这主要是由于队列时间的增加(见下图)。我尝试过celery的配置,并使用以下配置:

CELERY_MAX_CACHED_RESULTS = -1
CELERY_TASK_RESULT_EXPIRES=30
CELERYD_MAX_TASKS_PER_CHILD=5000
BROKER_URL = 'librabbitmq://guest@localhost//'
CELERY_RESULT_BACKEND = 'amqp://'
CELERYD_TASK_SOFT_TIME_LIMIT=1
CELERYD_TASK_TIME_LIMIT=2
CELERYD_WORKER_LOST_WAIT=2
CELERYD_PREFETCH_MULTIPLIER=16

我还运行4个uWSGI并发/预分叉,10个并行/预分叉芹菜工人。我注意到,当我将芹菜工人的数量增加到16个,但系统资源(CPU)开始达到最大值时,也会发生这种情况。在

有没有其他的Celery/RabbitMQ参数可以调整以尝试改进?失败的任务似乎与队列时间的增加相关,这可能是有意义的,因为工作人员被失败的任务占据,无法清除队列。就像一个级联效应。我只是需要更多的工人在一个更好的箱子里吗?在

queue times

更新1:我使用以下设置运行了第二个测试,并对我的应用程序代码进行了轻微修改,以减少进入队列的负载。在测试开始大约两个小时后,一些“事件”发生之前,它似乎运行得很顺利。还有什么可以用来监视队列的其他方面的吗?在

^{pr2}$

update 1 latency

更新2:我增加了工作进程的数量(3个工作进程有10个并发线程nohup celery -A tasks worker --loglevel=error --concurrency=10 -n worker1.%h &),并且看到了更多的稳定性,但是大约2小时后,API请求错误出现峰值,并导致我的应用程序的延迟显著增加。在

奇怪的是,我硬编码了3个级别的延迟超时:

  1. 在我的geventhttpclientHTTPClient(网络延迟=.8s)中 任务级
  2. 芹菜软超时=1.0s
  3. 芹菜(硬)超时=1.2

在发生故障时,这些上限应提供强有力的缓解措施,但显然不是这样。我也试着重新启动我的芹菜工人,但也没用。在

enter image description here

更新3-将geventhttpclient替换为我的HTTP请求模块,而只使用httplib,这不算幸运。也增加到--concurrenty=18。见下图:

我在这一点上被卡住了。。。在

enter image description here


Tags: 代码api应用程序task队列时间uwsgi数据源