在烧瓶端点内使用多处理(或多线程)的建议是什么



我知道应用程序服务器可以配置为:

  1. 根据请求启动新流程

  2. 按请求启动新线程

这个问题是关于在flask端点中使用python多处理(或多线程(代码。例如,我想使用python多处理进行CPU密集型工作(或多线程进行IO密集型工作(。

我有一个烧瓶端点,运行代码需要40秒(CPU密集型工作(。我在端点代码中使用了python多处理(池([这样某些CPU密集型的事情就可以通过多个进程并行完成],现在端点运行需要4秒。

当以上两种应用程序服务器配置中的任何一种时(即,当应用程序服务器被配置为在新线程中为每个请求或在新进程中为每个新请求提供服务时(,在端点内使用python多处理(或多线程(代码可以吗。每个请求的线程数是flask开发服务器的默认设置。至于gunicorn,我可以选择任何一个。在烧瓶端点内使用多处理(或多线程(时,我需要考虑什么吗?这样我就不会干扰烧瓶进程/线程。

我知道更好的解决方案是使用任务队列。但是这个问题是关于使用多线程/多处理的。

在Flask中使用多处理/线程池来运行后台或长时间运行的任务是一种反模式。你不应该这么做。Flask是用来提供API和CRUD的。

为了解决您的问题,请考虑使用API<gt;工人模式。

Flask app --- REDIS (or other MQ) --- Celery App
|                                         |
+---> SQL/Database <----------------------+

Flask将接收API请求并执行基本的CRUD(基本上是与数据库相关的任何操作(,仅此而已。

对于任何长时间运行的操作,将操作提交到DB中,句柄将排入redis/或任何消息队列。

芹菜是一个作业管理框架,它从队列中提取这些作业并执行它们(这些作业可能会运行很长一段时间(,并根据进度不断更新数据库。

芹菜:https://docs.celeryproject.org/en/stable/getting-started/introduction.html

简而言之,不要。尝试协商某种方式直接在请求处理程序中完成大量工作是很诱人的,但这种方式会带来痛苦。

相反,考虑其中一个框架,该框架允许请求处理程序(例如,Flask路由(对异步运行的任务进行排队。处理程序对工作进行排队,并返回任务id,以某种方式保存它,从而允许UI轮询任务完成情况。同时,flask之外的一个完全独立的过程会拾取工作,执行它,并通过框架(或单独通过共享数据存储(返回响应。

Celery和Rq就是其中的两个框架。(Flask Mega教程中有一章关于Rq,值得一读。(它们确实需要一些额外的设置。至少,您需要一个共享Redis实例。

这种方法有几个好处:首先,它允许你的网络应用程序保持响应。如果你的40秒任务演变成一个80、160或几千秒的任务,你就不会占用一个Flask线程。其次,它保护Flask不受内存增长和碎片的影响;该任务是在一个完全独立的进程中执行的,该进程将在退出时释放内存。

你在这些任务中所做的是与Flask无关的。想要在一个任务中使用多个进程或线程池吗?好的干扰Flask的风险很小。(*如果您在与Flask相同的服务器上运行任务工作者,则可能会耗尽内存(。

我认为它会按预期工作,由于子流程管理而导致的任何放缓都会得到十倍的加速补偿。

相关内容

  • 没有找到相关文章

最新更新