柴油应该使用同步执行器(sync actor)、actix_web::web::block还是futures-cpupool来运行?

16

背景

我正在使用diesel通过r2d2开发actix-web应用程序,但不确定如何最好地进行异步查询。我找到了三个看起来合理的选项,但不确定哪个是最好的。

潜在解决方案

同步Actor

首先,我可以使用actix示例,但这相当复杂,并且需要大量的样板文件来构建。我希望存在更合理的解决方案。

Actix_web::web::block

作为另一种选择,我可以使用actix_web::web::block将我的查询函数包装成一个future,但我不确定性能影响如何。

那么查询是否在同一个Tokio系统中运行?从源代码中可以找到它在底层的actix-web线程池中创建一个线程。这是一个问题吗?

如果我正确理解代码,r2d2在获取连接时会阻塞其线程,这将阻塞actix-web池的一部分。数据库查询也是如此。如果我执行的查询数超过该池中的线程数,则会阻塞整个actix-web。如果是这样,那就是一个大问题。

Futures-cpupool

最终,一个安全但可能有些不必要开销的选择是futures-cpupool。主要问题是这意味着在我的项目中添加另一个crate,尽管我不喜欢应用程序中不必要地出现多个CPU池的想法。

由于r2d2和diesel都会阻塞,因此这里有许多棘手的问题。

最重要的是,不要与未使用相同r2d2池的任何内容共享此cpupool(因为所有创建的线程可能只是等待r2d2连接而阻塞,当存在工作时锁定整个池)。

其次(更明显一些),因此您不应该拥有比池中的线程更多的r2d2连接,反之亦然,因为更大的那个将浪费资源(未使用的连接/常常被阻塞的线程)(也许还需要一个线程,以便操作系统调度程序可以更快地进行连接交接,而不是cpupool调度程序)。

最后,要注意您正在使用的数据库及其性能。在写入密集的SQLite应用程序中,运行单个连接r2d2和池中的单个线程可能是最佳选择(尽管我建议使用适当的数据库进行此操作)。

旧答案

可能有效的旧解决方案

https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/

实质上,推荐使用Futures-cpupool。

什么是将阻塞I/O封装在future-rs中的最佳方法?

一般情况下,推荐使用Futures-cpupool。

不起作用的旧解决方案

https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/

一个非常好的旧版本actix-web的修复。从我能找到的资料中,请求不再包含CPU池。


这个问题的评论中可以看出,futures-cpupool是在Diesel缺乏async支持时推荐的解决方法。 - Jmb
那是一个更为通用的解决方案。我希望能够利用actix系统来实现。尽管如此,我现在会深入研究futures-cpupool以寻找问题。 - logina
欢迎来到Stack Overflow!看起来您的问题可能已经在如何封装future-rs中的阻塞I/O的最佳方法?的答案中得到了解答。如果没有, 请**[编辑]**您的问题以解释差异。否则,我们可以将此问题标记为已回答。 - Shepmaster
由于cpupool还与r2d2中的阻塞连接池进行交互,我不确定如何最好地解决这个问题。我现在正在研究它,并将尽快更新。 - logina
1个回答

4

我选择使用futures-cpupool。由于我的交互具有阻塞性质,这是最佳解决方案。

使用actix_web::web::block也可以,但它将在actix中使用共享线程池(由于我使用的阻塞调用可能会阻塞整个线程池并干扰给actix_web的其他任务)。

最好使用futures-cpupool为每个数据库创建单独的线程池,只用于数据库交互。这样,您将需要等待彼此的所有任务(当任务数多于连接数时)分组到一个池中,防止它们阻塞任何不需要连接的其他任务,并潜在地将线程数限制为连接数(这样只有在任务不被阻塞时才会安排)。

如果您只想使用一个数据库连接(或很少),那么同步Actor是一个相当不错的选择。它会像futures-cpupool一样使用一个线程,确保所有任务依次运行,但它将使用actix-web的基础线程之一而不是单独的线程池(因此仅适用于非常少量的连接)。尽管如此,我认为它的样板代码太多了,不值得这样做。


7
阅读我上面的发现 — 请将与答案相关的信息放在答案中,而不是问题中。 - Shepmaster
你会推荐什么样的线程池大小? - Ari Seyhun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接