您需要异步处理此任务,因为它是一项长时间运行的作业,会显着降低 HTTP 响应的性能(如果您等到它完成)。
此外,您可能会注意到您需要在为您的 HTTP 请求提供服务的当前进程的单独进程中运行此任务。因为,Web 服务器(Gunicorn、uWSGI 等)将生成它们创建的进程并在需要时释放系统资源。您很容易出现通过 Ajax 启动的异步进程将被 Web 服务器中断和终止的情况,因为您关闭了浏览器(请求关闭)。所以,threading
并不是coroutines
完成这项任务的最佳工具。
这就是为什么有一些很酷Task queue
的项目可以解决您的问题。我们可能会注意到:
- Celery:(生产就绪解决方案)它是一个任务队列,专注于实时处理,同时还支持任务调度。与消息代理一起工作
Redis
并RabbitMQ
用作消息代理
- RQ (Redis Queue) : RQ (Redis Queue) 是一个简单的 Python 库,用于对作业进行排队并在后台与工作人员一起处理它们。它由 Redis 支持,旨在降低进入门槛。它可以轻松集成到您的 Web 堆栈中。
- Taskmaster:Taskmaster 是一个简单的分布式队列,设计用于处理大量一次性任务。
- Huey:是一个基于 Redis 的任务队列,旨在为执行任务提供一个简单而灵活的框架。Huey 支持任务调度、类似 crontab 的重复任务、结果存储和发生故障时的自动重试。
- Dramatiq:是 Celery 的快速可靠的替代品。它支持 RabbitMQ 和 Redis 作为消息代理。
- APScheduler : Advanced Python Scheduler (APScheduler) 是一个 Python 库,可让您安排 Python 代码稍后执行,无论是一次还是定期执行。
还有很多 !
随着你的崛起,micro services
你可以结合和的力量,Task queues
你containers
可以构建一个单独的容器来处理你的长时间运行的任务(并根据你当前的情况更新你的数据库)。此外,如果您还不能使用micro services
架构,您可以构建一个单独的服务器来处理这些任务,并使处理用户请求的 Web 服务器免于运行长时间运行的任务。
最后,您可以在您当前的网站中组合这些解决方案,如下所示:
- 用户点击一个按钮。
- Ajax 请求触发您的后端(通过 API 或其他方式)
- 您在代理消息中安排一个任务以现在或稍后运行它(在单独的容器/VPS 中......)
- 在您的后端,您检索
Task ID
任务的
- 您返回
Task ID
by API 或其他任何内容,然后将其添加到会话 cookie 或处理启动流程的用户的单独表中。
- 在某些 JS 中,您不断从您的后端请求任务的状态
Task ID
(在用户会话 cookie 中或在您的数据库中)
- 即使用户关闭了他的浏览器,该任务也将继续其操作,直到它完成或引发异常。在您已经拥有的任务 ID 中,您可以轻松了解此任务的状态并将此信息发送给用户(在他再次登录时的视图中,通过电子邮件等......)
并且确保您可以改善这种情况!