第十八章 Akka¶
Akka用于构建高并发可扩展应用,它的容错性很高。
actor系统¶
Akka工作在 actor
系统之上, actor
系统用于管理资源。
Play应用定义了一个特殊的 actor
系统,这个系统的生命周期与 play
应用的生命周期保持一致。
定义actors¶
使用Akka之前,需要先创建一个 actor
:
import akka.actor._
object HelloActor {
def props = Props[HelloActor]
case class SayHello(name: String)
}
class HelloActor extends Actor {
import HelloActor._
def receive = {
case SayHello(name: String) =>
sender() ! "Hello, " + name
}
}
上面的 actor
遵守了Akka规范:
- 发送或者接受的消息以及协议, 都定义在伴生对象中
- 定义了props方法
创建和使用actors¶
创建actor,需要使用 ActorSystem
,通过依赖注入实现:
import play.api.mvc._
import akka.actor._
import javax.inject._
import actors.HelloActor
@Singleton
class Application @Inject() (system: ActorSystem) extends Controller {
val helloActor = system.actorOf(HelloActor.props, "hello-actor")
//...
}
actorOf
方法用来创建 actor
,注意这里 Controller
声明为单例类,这是因为 actor
与类相关联,不能创建两个名字相同的 actor
。
发送消息¶
actor
最基本的用法就是发送消息,当发送消息给 actor
的时候,并没有返回。
但是HTTP是需要返回的,这时可以返回 Future
结果类型。
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.duration._
import akka.pattern.ask
implicit val timeout: Timeout = 5.seconds
def sayHello(name: String) = Action.async {
(helloActor ? SayHello(name)).mapTo[String].map { message =>
Ok(message)
}
}
需要注意的是:
- 使用
?
操作符表示等待返回 - 返回结果是
Future[Result]
类型 - 需要声明隐式参数
timeout