我有一个场景,我必须通过用户的 ID 获取用户的详细信息。这是一个传入 HTTP 处理程序层的 HTTP 请求,我利用从请求中获取的 id,向 Actor 发送一条消息,然后 Actor 与数据库服务通信以获取用户。
现在,由于这是一个 HTTP 请求,我需要通过发回响应来满足该请求。所以我想到使用 Akka Ask 模式,但我有以下问题:
这会阻塞我当前的线程吗?
在我的例子中,使用询问模式来获取用户是一个可扩展的解决方案吗?我的意思是,在任何给定时间点,我都可能有数百到一百万用户调用此端点。使用询问模式来获取用户是一个好主意吗?
在代码中,它在我的 HTTP 控制器中看起来像这样
val result: Future[Any] = userActor ? FetchUser(id)
Run Code Online (Sandbox Code Playgroud)
在我的演员中,我会做以下事情:
case fetchUser: FetchUser => sender ! myService.getUser(fetchUser.id)
Run Code Online (Sandbox Code Playgroud)
按照您提出问题的顺序回答您的问题:
?不会阻塞当前线程。它Future立即返回一个。然而,未来的结果可能无法立即获得。?一次为多个服务提供服务,或者参见下面的仅 Futures 的可扩展解决方案。期货独家
如果你的 Actors 没有缓存任何中间值,那么你可以直接使用 Futures 并避免 Actors 的繁琐(例如 Props、actorOf、receive、?、...):
import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext,Future}
object ServicePool {
private val myService = ???
val maxQueries = 11 //should come from a configuration file instead
private val queryExecutionPool =
ExecutionContext.fromExecutor(Executors.newFixedThreadPool(maxQueries))
type ID = ???
/**Will only hit the DB with maxQueries at once.*/
def queryService(id : ID) =
Future { myService getUser id }(queryExecutionPool)
}//end object ServiceQuery
Run Code Online (Sandbox Code Playgroud)
现在,您可以ServicePool.queryService根据需要多次调用,但服务不会受到多次调用maxQueries,并且不会出现任何 Actor:
val alotOfIDs : Seq[ID] = (1 to 1000000) map { i => ID(i)}
val results = alotOfIDs map ServicePool.queryService
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1384 次 |
| 最近记录: |