Akka Ask 是否阻塞当前线程 [英] Is Akka Ask Blocking on the Current Thread
问题描述
我有一个场景,我必须通过他的 id 获取用户的详细信息.这是一个进入我的 HTTP 处理程序层的 HTTP 请求,我利用从请求中获得的 id,向参与者发送一条消息,然后参与者与数据库服务对话以获取用户.
I have a scenario where I have to fetch the details of a user by his id. It is a HTTP request that comes in and in my HTTP handler layer, I make use of the id that I get from the request, send a message to the actor which then talks to the database service to fetch the user.
现在由于这是一个 HTTP 请求,我需要通过发回响应来满足请求.于是想到了使用Akka ask模式,但心里有以下几个问题:
Now since this is a HTTP request, I need to satisfy the request by sending a response back. So I thought of using the Akka ask pattern, but I have the following questions in mind:
这会阻塞我当前的线程吗?
Is this going to block on my current thread?
在我的案例中,这里使用询问模式来获取用户是一种可扩展的解决方案吗?我的意思是,在任何给定的时间点,我都可能有数百到一百万用户呼叫此端点.使用询问模式获取用户是否是个好主意?
Is using ask pattern here to fetch a user in my case a scalable solution? I mean, I could have a few hundreds to a million users calling this end point at any given point in time. Is this a good idea to use the ask pattern to fetch a user?
在代码中,它在我的 HTTP 控制器中看起来像这样
In code, it looks like this in my HTTP controller
val result: Future[Any] = userActor ? FetchUser(id)
在我的演员中,我会做以下事情:
In my actor, I would do the following:
case fetchUser: FetchUser => sender ! myService.getUser(fetchUser.id)
推荐答案
按照您提出问题的顺序回答问题:
Answering your questions in the same order you posed them:
- 否,使用
?
不会阻塞当前线程.它立即返回一个Future
.但是,Future 中的结果可能无法立即获得. - 如果您需要解决方案具有可扩展性",并且您的服务能够进行多个并发查询,那么您可能需要使用 池 Actors 这样你就可以同时服务多个
?
,或者只见下面的 Futures,可扩展, 解决方案.
- No, using the
?
does not block the current thread. It returns aFuture
immediately. However, the result within the Future may not be available immediately. - If you need the solution to be "scalable", and your service is capable of multiple concurrent queries, then you may need to use a pool of Actors so you can serve multiple
?
at once, or see below for a Futures only, scalable, solution.
独家期货
如果您的 Actors 没有缓存任何中间值,那么您可以直接使用 Futures 并避免 Actors 的繁琐(例如 Props、actorOf、receive、?、...):
If your Actors are not caching any intermediate values then you can just use Futures directly and avoid the rigmarole of Actors (e.g. 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
您现在可以随心所欲地调用 ServicePool.queryService
,但该服务一次不会被超过 maxQueries
命中,并且没有 Actor:
You can now call ServicePool.queryService
as often as you want but the service will not be hit with more than maxQueries
at a single time, and no Actors:
val alotOfIDs : Seq[ID] = (1 to 1000000) map { i => ID(i)}
val results = alotOfIDs map ServicePool.queryService
这篇关于Akka Ask 是否阻塞当前线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!