我有一个使用Akka的Scala应用程序,它接收REST请求,对数据库进行一些操作,并向客户端响应一些信息。实际上,我的DB操作需要很长时间,而启用REST的参与者在此期间无法响应新的请求,尽管我可以同时对db运行许多操作。我在我的参与者中使用javax.ws.rs注释来启用REST方法。
问题:使我的应用程序能够处理大量并发请求的最佳方法是什么?
编辑:我将添加一些示例代码。
import se.scalablesolutions.akka.actor._
import javax.ws.rs._
@Path("/test")
class TestService {
@GET
def status() =
actorPool !! Status(session).
getOrElse(<error>Unable to connect to service</error>)
}
class TestActor {
def receive = {
case Status() => {
reply(SomeObject.slowDBMethod)
}
}
}
case class Status()EDIT2:这就是我在日志中得到的。我将尽可能快地从浏览器中发送这三个请求,并按下一个选项卡,但在处理下一个请求之前,RS仍然在等待第一个请求完成。
[INFO] [2010-08-29 16:27:03,232] [akka:event-driven:dispatcher:global-15] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:06,916] [akka:event-driven:dispatcher:global-10] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:10,589] [akka:event-driven:dispatcher:global-3] c.n.StatusActor: got Slow request发布于 2010-12-21 19:55:52
虽然我意识到这个线程现在已经过时了,但是值得注意的是,Akka有一个新的4+模块实现,可以高效地将请求转换为一个参与者。这种方法利用异步servlet (也适用于Jetty连续),使挂起的请求能够作为消息在系统中传递,并在任何时候继续进行;例如,无需使用!!在带注释的POJO中触发参与者的工作和响应。同样,由于请求挂起在容器中,并且上下文被尽可能快地翻转到一个参与者中,所以没有线程阻塞来处理响应或未来。
今天可能改写上述示例的一种天真的方式是:
class TestEndpoint extends Actor with Endpoint {
def hook(uri:String) = uri == "/test"
def provide(uri:String) = actorOf[TestService].start
override def preStart = {
ActorRegister.actorsFor[classOf[RootEndpoint]).head ! Endpoint.Attach(hook, provide)
}
def receive = handleHttpRequest
}
class TestService extends Actor {
def receive = {
case get:Get =>
get.timeout(SomeObject.TimeoutInSeconds) // for example
get.OK(SomeObject.slowDBMethod)
case other:RequestMethod =>
other.NotAllowed("Invalid method for this endpoint")
}
}更多的文档可以在akka站点上找到:http://doc.akkasource.org/http
发布于 2010-08-22 13:49:12
你似乎在使用更老版本的Akka。
我建议升级到0.10 (将Actors和RS-Beans分开),然后可以使用LoadBalancer1 (和2)来控制工作负载,或者利用WorkStealingDispatcher3. (和4.)
这有用吗?
发布于 2010-08-21 23:12:18
一旦收到请求,就应该创建一个新的参与者来处理该请求。传递原始发送方,以便新创建的演员知道该对谁负责。
https://stackoverflow.com/questions/3539274
复制相似问题