我想调用一个包含大量数据的数据库,并且可能需要一段时间才能返回。
我计划在对 Akka.future(f) 的调用中完成这项工作,并在工作完成后使用 Async{} 呈现响应。
这样做是否有意义,或者我应该只在控制器中进行长时间的数据库调用,而不将工作发送给 Akka?
或者有没有办法进行非阻塞数据库访问?
我想调用一个包含大量数据的数据库,并且可能需要一段时间才能返回。
我计划在对 Akka.future(f) 的调用中完成这项工作,并在工作完成后使用 Async{} 呈现响应。
这样做是否有意义,或者我应该只在控制器中进行长时间的数据库调用,而不将工作发送给 Akka?
或者有没有办法进行非阻塞数据库访问?
如果您被迫为您的数据库使用阻塞驱动程序(如果由于某种原因 MySQL 的异步驱动程序不起作用),请考虑使用 PinnedDispatcher 设置一个 Actor 池(使用路由)。
PinnedDispatcher 为每个参与者提供一个线程,并且通过设置路由器,您可以调整严格负责处理数据库调用的线程数。易于缩放。此外,通过使用 Actors,您可以更轻松地构建 Actor 之间的消息(例如,具有数据库调用结果的消息)。
您可以使用Akka.future(f)
并提供您自己的 Akka 配置文件来获得更多线程来处理您的数据库访问。例如看这个配置文件。
但是您指出了:真正的问题在于使用阻塞的数据库驱动程序。我不知道您使用的是哪个数据库,但值得以ReactiveMongo为例来看看 MongoDB。使用 ReactiveMongo,所有 MongoDB 操作都是完全非阻塞和异步的。这里有很好的介绍。此外,它很好地处理了 Play 框架(检查ReactiveMongo Play 插件)。
编辑:您还可以检查“配置 Playframework 的内部 Akka 系统”来调整工作线程数。
如果响应在数据库调用完成时被阻塞,那么只有在调用运行时您可以完成其他工作来组装响应时,才使其异步有用。
非阻塞数据库访问可能意味着几件不同的事情:一个为您提供基于回调的 API 的客户端库,这与未来的解决方案非常相似,或者一个使用非阻塞套接字来节省线程使用的客户端库。我假设您的意思是前者,在这种情况下,我认为它在功能上等同于使用未来。