提交 b030c775 编写于 作者: 梦境迷离's avatar 梦境迷离

修改笔误,时间:2019-11-03 20:36:58

上级 97a98041
......@@ -18,11 +18,11 @@ libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.25"
### 创建actor
Akka强制执行家长监督,每个actor都受到监督,而且(潜在的)监督其子女
Akka强制执行家长监督,每个actor都受到监督,而且(潜在的)监督其子女
#### 定义Actor类
actor通过扩展Actor基本特质和实现receive方法来实现。receive方法应该定义一系列case语句(其类型为PartialFunction[Any,Unit]),使用标准Scala模式匹配定义您的Actor可以处理哪些消息,以及应该如何处理消息的实现。
actor通过扩展Actor基本特质和实现receive方法来实现。receive方法应该定义一系列case语句(其类型为PartialFunction[Any,Unit]),使用标准Scala模式匹配定义您的Actor可以处理哪些消息,以及应该如何处理消息的实现。
```scala
......@@ -40,7 +40,7 @@ class MyActor extends Actor {
}
```
Akka actor的receive message消息匹配的遍历是彻底的,与Erlang和Scala Actors(已废弃)不同。这意味着您需要为它可以接受的所有消息提供模式匹配,如果您希望能够处理未知的消息,那么您需要有一个默认的case,如上面的示例所示。
Akka actor的receive message消息匹配的遍历是彻底的,与Erlang和Scala Actors(已废弃)不同。这意味着您需要为它可以接受的所有消息提供模式匹配,如果您希望能够处理未知的消息,那么您需要有一个默认的case,如上面的示例所示。
否则akka.actor.UnhandledMessage(message, sender, recipient)将发布到ActorSystem的EventStream。
上面定义的行为的返回类型是Unit,如果actor应回复所收到的消息,则必须按照下文解释明确地这样做。receive方法的结果是一个部分函数对象,该对象作为其“初始行为”存储在actor中。
......@@ -176,7 +176,7 @@ val actorRef = system.actorOf(Props(classOf[DependencyInjector], applicationCont
#### 收件箱(信箱)
当编写与actor通信的外部代码时,ask模式可以是解决方案(见下文),但它不能做两件事:接收多个答复(例如,通过订阅ActorRef)和监视其他actor的生命周期。为此目的,有Inbox class:
当编写与actor通信的外部代码时,ask模式可以是解决方案(见下文),但它不能做两件事:接收多个答复(例如,通过订阅ActorRef)和监视其他actor的生命周期。为此目的,有Inbox class:
```scala
import akka.actor.ActorDSL._
......@@ -241,7 +241,7 @@ class MyActor extends Actor {
#### 回复消息
如果您想拥有回复消息的句柄,可以使用sender() ,这给了你一个actor的ActorRef。您可以通过向ActorRef发送sender() ! replyMsg。
您还可以存储ActorRef,以便稍后回复,或传递给其他actor。如果没有发送者(消息是在没有actor或Future上下文的情况下发送的),则发送方默认为“死信”actor引用。
您还可以存储ActorRef,以便稍后回复,或传递给其他actor。如果没有发送者(消息是在没有actor或Future上下文的情况下发送的),则发送方默认为“死信”actor引用。
```scala
sender() ! x // replies will go to this actor
......@@ -373,62 +373,51 @@ actor生命周期:
当消息正在由actor处理时,可能会引发某种类型的异常,例如数据库异常等。
下面是一个简单的容错处理异常的例子:
通过重写监督方法可以对异常进行必要的处理,下面是一个简单的例子:
```scala
import akka.actor.Actor
/**
* actor四大默认存在的方法
* 类似Java Servlet
* @author 梦境迷离
* @time 2019-02-11
*/
class ShoppingCart extends Actor {
//必须拓展(混入)Actor特质【UntypedAbstractActor特质也可以,实现非类型化的actor】
//按照逻辑排序的四个方法
//开始之前,大多数情况下需要重写
//代码块的代码被删除了
//杀死所有孩子actor
override def preStart(): Unit = {}
//终止之后,大多数情况下需要重写
override def postStop(): Unit = {}
//重启之前,通常不需要重写
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {}
//重启之后,默认调用preStart,通常不需要重写
/** Actor源码该方法中
* def postRestart(reason: Throwable): Unit = {
* preStart()
* }
*/
override def postRestart(reason: Throwable): Unit = {}
//用户编写的代码至少支持receive代码块(重写)
override def receive = {
//处理所有类型消息并不作处理
case _ =>
```scala
//AllForOneStrategy,影响同级或同层所有actor
override def supervisorStrategy: SupervisorStrategy = AllForOneStrategy(maxNrOfRetries = 5, Duration.create("1 minute"), true) {
//索引是IO操作,挂了就停止
case _: IndexingException => Escalate
//重启,Restart不保留状态,重新抓取页面
case re: RetrievalException => {
if (re.url != null) {
logger.warn("url {} has an exception", re.url)
VisitedPageStore.finished(re.url)
}
Resume
}
//代理异常,忽略
case pe: ProxyException => {
if (pe.url != null) {
logger.warn("url {} has an exception", pe.url)
VisitedPageStore.finished(pe.url)
}
Escalate
}
//其他异常
case _: Exception => Stop
}
}
```
##### 对于消息来说发生了什么
如果在处理消息时抛出异常,则此消息将丢失。
重要的是要明白,它没有放回邮箱。因此,如果您想要重新尝试处理一条消息,您需要自己处理它,捕捉异常并重试您的流。
确保您绑定了重试次数,因为您不希望系统发生活锁(这样就会消耗大量的CPU周期而不会取得有意义的进展)
确保您绑定了重试次数,因为您不希望系统发生活锁(这样就会消耗大量的CPU周期而不会取得有意义的进展)
##### 对于信箱(邮箱)来说发生了什么
##### 对于信箱(邮箱)来说发生了什么
如果在处理消息时引发异常,则邮箱不会发生任何情况。如果重新启动该actor,则将存在相同的邮箱。所以邮箱上的所有信息(消息)都会在那里而不会丢失。
如果在处理消息时引发异常,则邮箱不会发生任何情况。如果重新启动该actor,则将存在相同的邮箱。所以邮箱上的所有信息(消息)都会在那里而不会丢失。
##### 对于actor来说发生了什么
如果actor中的代码抛出异常,则暂停该actor并启动监视过程(请参阅监督与检测)
这取决于主管(上级)actor的决定,actor可以被恢复(好像什么都没发生)、也可以被重新启动(清除内部状态并从头开始)或者被终止。
如果actor中的代码抛出异常,则暂停该actor并启动监视过程(请参阅监督与监控)
这取决于主管(上级)actor的决定,actor可以被恢复(好像什么都没发生)、也可以被重新启动(清除内部状态并从头开始)或者被终止。
### 其他
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册