我是否应该使用任务队列(Celery),ayncio或者不使用轮询其他API的API?

Rém*_*ult 4 django api-design task-queue celery

我已经用Django编写了一个API,其目的是作为网站后端和我们使用的外部服务之间的桥梁,这样网站就不必处理对外部API的许多请求(CRM,日历事件,电子邮件提供商)等等.).

API主要轮询其他服务,解析结果并将其转发到网站后端.

我最初选择了基于Celery的任务队列,因为在我看来,这是将该处理卸载到另一个实例的正确工具,但我开始认为它并不适合这个目的.

由于网站需要同步响应,我的代码包含很多:

results = my_task.delay().get()

要么

results = chain(fetch_results.s(), parse_results.s()).delay().get()

哪种感觉不适合使用Celery任务.

在拉动数十个请求并并行处理结果(例如定期刷新任务)时效率很高- 但为简单请求(fetch - parse-forward)增加了大量开销,这代表了大部分流量.

我是否应该完全同步这些"简单请求"并保留Celery任务用于特定场景?是否有更符合我的API目的的替代设计(可能涉及asyncio)?


在EBS EC2实例上使用Django,Celery(带有Amazon SQS).

vin*_*nod 5

您可以考虑将Gevent与Django Web服务器一起使用,以使其能够有效地运行您提到的"简单请求"而不会被阻止.如果继续这种方法,请确保使用PgBouncer或Pgpool-II或Python库来池化数据库连接,因为每个greenlet都会建立自己的连接.

一旦实现了这一点,就可以使用Gevent代替Celery来处理异步处理,方法是连接多个Greenlet,每个Greenlet都会发出外部API请求,而不是产生将消息传递给外部芹菜工作者的开销.

您的实现类似于我们在Kloudless上所做的,它提供了一个API来访问多个其他API,包括CRM,日历,存储等.

  • 当然确实取决于手头的任务:我们实际上选择了 Celery 进行大部分处理,因为我们还想启动定期后台作业,并且我们希望在多个后台 API 请求正在进行时最小化网络服务器上的负载,以便我们可以扩展那些工人分开。因此,我在监控 greenlet 方面没有那么多经验,但我们确实大量使用这些来执行主 API 服务器中更简单的异步任务。我们在开发过程中并没有考虑太多 eventlet。 (2认同)