Background
我正在使用diesel通过r2d2开发一个actix web应用程序,不确定如何最好地进行异步查询.我找到了三个似乎合理的 Select ,但不确定哪一个是最好的.
Potential Solutions
同步演员
例如,我可以使用the actix example,但它相当复杂,需要大量的样板来构建.我希望有一个更合理的解决方案.
Actix_web::web::block
作为另一种 Select ,我可以使用actix_web::web::block
将我的查询函数包装到future ,但我不确定这对性能的影响.
那么这个查询是在同一个Tokio系统中运行的吗?根据我在资料中找到的it creates a thread in the underlying actix-web threadpool.这有问题吗?
如果我读对了代码,r2d2在获取连接时会阻塞其线程,这会阻塞核心actix web池的一部分.数据库查询也是如此.如果我做的查询比池中的线程多,这会阻止所有actix web吗?如果是的话,那就是一个大问题.
期货cpupool
最后,可能有一些不必要的开销的安全赌注是futures-cpupool.主要的问题是,这意味着在我的项目中添加另一个 crate ,尽管我不喜欢在我的应用程序中不必要地浮动多个cpu池的 idea .
因为r2d2和柴油机都会堵塞,所以这里有很多棘手的事情.
最重要的是,不要与不使用相同r2d2池的任何线程共享此cpupool(因为创建的所有线程可能只是阻塞等待r2d2连接,在有工作时锁定整个池).
其次(更明显一点),因此池中的r2d2连接不应该比线程多,反之亦然,因为较大的r2d2连接会浪费资源(未使用的连接/线程不断被阻塞)(可能多一个线程,以便OS调度器而不是cpupool调度器更快地进行连接切换).
最后,请注意您正在使用的数据库及其性能.在编写量大的sqlite应用程序中,运行单个连接r2d2和池中的单个线程可能是最好的(尽管我建议为此类应用程序使用合适的数据库).
Old answers
可能有效的旧解决方案
https://www.reddit.com/r/rust/comments/axy0hp/patterns_to_scale_actixweb_and_diesel/
本质上,cpupool是.
What is the best approach to encapsulate blocking I/O in future-rs?
建议在一般情况下使用cpupool.
不起作用的旧解决方案
https://www.reddit.com/r/rust/comments/9fe1ye/noob_here_can_we_talk_about_async_and_databases/
对于旧的actix web版本来说,这是一个非常好的修复.据我所知,请求中不再有cpu池.