如何 运行 Python 3 即使在用户关闭网络 browser/tab 后仍能正常运行?
How to run Python 3 function even after user has closed web browser/tab?
我在处理我正在处理的 python 项目时遇到问题(我通常使用 PHP/Java,所以缺乏一些知识)。
基本上我有一个使用 Flask 构建的 python 程序,它使用 Shopify Python API.
将库存管理系统连接到 Shopify
当用户通过 AJAX 请求触发功能时,我需要启动一个 function/process 通过 Shopify API 更新客户 Shopify 商店中的产品。这大约需要 2 小时(约 7000 种产品,而且必须先从库存管理系统中提取它们)。
问题是我需要一种可以触发此 function/process 的方法,即使客户端关闭浏览器 function/process 也会继续 运行.
如果有任何方法我可以用这个背景的当前进度更新前端function/process,那就太棒了。
如果有人知道完成此任务的任何库或资源,将不胜感激。
我有一个 google,但我能找到的所有解决方案似乎都是针对 CLI 脚本而不是 Web 脚本的。
多谢,
科里 :)
通常您会创建一个任务,然后 return 向用户提供一个 id,他可以使用它来汇总所述任务的状态。
然后您将在另一个 container\process\thread 中处理任务。
Celery 是一个 Python 库,可以帮助您进行设置。
另一种常见的解决方案是使用 publisher\subscriber 设计并使用分布式队列,例如 Kafka、RabbitMQ 甚至 Redis。
事实上,Celery 可以使用 RabbitMQ 或 Redis 作为其消息代理。
您需要异步处理此任务,因为它是一项耗时 运行 的作业,会显着降低 HTTP 响应的性能(如果您等到它完成)。
此外,您可能会注意到您需要 运行 在为您的 HTTP 请求提供服务的当前进程的单独进程中执行此任务。因为,Web 服务器(Gunicorn、uWSGI 等)将生成它们创建的进程并在需要时释放系统资源。您很容易会遇到这样的情况,即通过 Ajax 启动的异步进程将被 Web 服务器中断并终止,因为您关闭了浏览器(请求已关闭)。因此,threading
和 coroutines
不是完成此任务的最佳工具。
这就是为什么有一些很棒的 Task queue
项目可以解决您的问题。我们可能会注意到:
- Celery: (Production ready solution) 一个专注于实时处理的任务队列,同时也支持任务调度。作为消息代理与
Redis
和 RabbitMQ
配合使用效果很好
- RQ (Redis Queue):RQ(Redis 队列)是一个简单的 Python 库,用于排队作业并在后台与工作人员一起处理它们。它由 Redis 支持,旨在降低进入门槛。它可以很容易地集成到您的网络堆栈中。
- Taskmaster: Taskmaster 是一个简单的分布式队列,专为处理大量一次性任务而设计。
- Huey:是一个基于Redis的任务队列,旨在为执行任务提供一个简单而灵活的框架。 Huey支持任务调度,类似crontab的重复任务,结果存储,失败自动重试。
- Dramatiq:是 Celery 的快速可靠替代品。它支持 RabbitMQ 和 Redis 作为消息代理。
- APScheduler: Advanced Python Scheduler (APScheduler) 是一个 Python 库,可让您安排 Python 代码稍后执行,一次或定期执行.
还有更多!
随着 micro services
的兴起,您可以结合 Task queues
和 containers
的强大功能,构建一个单独的容器来处理您的长 运行ning 任务(并根据当前情况更新您的数据库)。此外,如果您还不能使用 micro services
架构,您可以构建一个单独的服务器来处理这些任务,并使处理用户请求的 Web 服务器免于 运行 长时间 运行宁任务。
最后,您可以像这样在您当前的网站中组合这些解决方案:
- 用户点击按钮。
- Ajax 请求触发您的后端(通过 API 或其他方式)
- 您现在或稍后(在单独的 container/VPS... 中)运行 在代理消息中安排任务
- 在您的后端,您检索任务的
Task ID
- 你 return API 的
Task ID
或其他任何东西,然后将其添加到会话 cookie 或单独的 table 中,它与启动该过程的用户打交道.
- 在某些 JS 中,您不断通过
Task ID
从后端请求任务的状态(在用户会话 cookie 或数据库中)
- 即使用户关闭了他的浏览器,该任务也会继续其操作,直到它完成或引发异常。在您已经拥有的任务 ID 中,您可以轻松了解此任务的状态并将此信息发送给用户(在他再次登录时的视图中,通过电子邮件等...)
当然你可以改进这个场景!
我在处理我正在处理的 python 项目时遇到问题(我通常使用 PHP/Java,所以缺乏一些知识)。 基本上我有一个使用 Flask 构建的 python 程序,它使用 Shopify Python API.
将库存管理系统连接到 Shopify当用户通过 AJAX 请求触发功能时,我需要启动一个 function/process 通过 Shopify API 更新客户 Shopify 商店中的产品。这大约需要 2 小时(约 7000 种产品,而且必须先从库存管理系统中提取它们)。 问题是我需要一种可以触发此 function/process 的方法,即使客户端关闭浏览器 function/process 也会继续 运行.
如果有任何方法我可以用这个背景的当前进度更新前端function/process,那就太棒了。
如果有人知道完成此任务的任何库或资源,将不胜感激。 我有一个 google,但我能找到的所有解决方案似乎都是针对 CLI 脚本而不是 Web 脚本的。
多谢, 科里 :)
通常您会创建一个任务,然后 return 向用户提供一个 id,他可以使用它来汇总所述任务的状态。
然后您将在另一个 container\process\thread 中处理任务。
Celery 是一个 Python 库,可以帮助您进行设置。
另一种常见的解决方案是使用 publisher\subscriber 设计并使用分布式队列,例如 Kafka、RabbitMQ 甚至 Redis。
事实上,Celery 可以使用 RabbitMQ 或 Redis 作为其消息代理。
您需要异步处理此任务,因为它是一项耗时 运行 的作业,会显着降低 HTTP 响应的性能(如果您等到它完成)。
此外,您可能会注意到您需要 运行 在为您的 HTTP 请求提供服务的当前进程的单独进程中执行此任务。因为,Web 服务器(Gunicorn、uWSGI 等)将生成它们创建的进程并在需要时释放系统资源。您很容易会遇到这样的情况,即通过 Ajax 启动的异步进程将被 Web 服务器中断并终止,因为您关闭了浏览器(请求已关闭)。因此,threading
和 coroutines
不是完成此任务的最佳工具。
这就是为什么有一些很棒的 Task queue
项目可以解决您的问题。我们可能会注意到:
- Celery: (Production ready solution) 一个专注于实时处理的任务队列,同时也支持任务调度。作为消息代理与
Redis
和RabbitMQ
配合使用效果很好 - RQ (Redis Queue):RQ(Redis 队列)是一个简单的 Python 库,用于排队作业并在后台与工作人员一起处理它们。它由 Redis 支持,旨在降低进入门槛。它可以很容易地集成到您的网络堆栈中。
- Taskmaster: Taskmaster 是一个简单的分布式队列,专为处理大量一次性任务而设计。
- Huey:是一个基于Redis的任务队列,旨在为执行任务提供一个简单而灵活的框架。 Huey支持任务调度,类似crontab的重复任务,结果存储,失败自动重试。
- Dramatiq:是 Celery 的快速可靠替代品。它支持 RabbitMQ 和 Redis 作为消息代理。
- APScheduler: Advanced Python Scheduler (APScheduler) 是一个 Python 库,可让您安排 Python 代码稍后执行,一次或定期执行.
还有更多!
随着 micro services
的兴起,您可以结合 Task queues
和 containers
的强大功能,构建一个单独的容器来处理您的长 运行ning 任务(并根据当前情况更新您的数据库)。此外,如果您还不能使用 micro services
架构,您可以构建一个单独的服务器来处理这些任务,并使处理用户请求的 Web 服务器免于 运行 长时间 运行宁任务。
最后,您可以像这样在您当前的网站中组合这些解决方案:
- 用户点击按钮。
- Ajax 请求触发您的后端(通过 API 或其他方式)
- 您现在或稍后(在单独的 container/VPS... 中)运行 在代理消息中安排任务
- 在您的后端,您检索任务的
Task ID
- 你 return API 的
Task ID
或其他任何东西,然后将其添加到会话 cookie 或单独的 table 中,它与启动该过程的用户打交道. - 在某些 JS 中,您不断通过
Task ID
从后端请求任务的状态(在用户会话 cookie 或数据库中) - 即使用户关闭了他的浏览器,该任务也会继续其操作,直到它完成或引发异常。在您已经拥有的任务 ID 中,您可以轻松了解此任务的状态并将此信息发送给用户(在他再次登录时的视图中,通过电子邮件等...)
当然你可以改进这个场景!