0Pricing
Scala for Backend Engineering & Functional Programming · 课时

设计 Actor 系统

学习设计并实现 Actor 层次结构、定义 Actor 行为,以及发送和接收消息。

设计 Actor 系统 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 2 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 3 节课。

设计 Actor 系统:简介

欢迎来到第 2 课!在上一课中,我们学习了 Akka Actor 模型的基础知识。现在,让我们深入了解 Akka Actor 系统的设计。

设计良好的 Actor 系统可靠、可扩展且易于维护。我们将探索如何组织 Actor、定义它们的行为,并使它们能够有效地通信。

理解 Actor 层次结构

Akka Actor 按树状层次结构组织,非常像文件系统。除了“根”Actor 之外,每个 Actor 都有一个父级。

  • 父子关系:创建另一个 Actor 的 Actor 会成为它的父级。
  • 监管:这一层次结构对于 Akka 的容错能力至关重要。父 Actor 负责监管其子 Actor(下一课将详细介绍这一点!)。
  • 基于路径的寻址:每个 Actor 都有唯一的路径,反映其在层次结构中的位置,例如 /user/parentActor/childActor。

设置您的 ActorSystem

ActorSystem 是所有 Akka 应用程序的入口点。它管理 Actor 所需的资源,包括线程池和调度器。

每个应用程序只需创建一次 ActorSystem,然后使用它创建顶层 Actor。它就像整个 Actor 应用程序的容器。

尝试运行以下简单代码来创建 ActorSystem:

import akka.actor.ActorSystem

object AkkaSystemApp {
  def main(args: Array[String]): Unit = {
    // Create an ActorSystem with a unique name
    val system = ActorSystem("MyFirstActorSystem")
    println("ActorSystem created: " + system.name)

    // Remember to terminate the system when done!
    system.terminate()
  }
}

定义 Actor 行为

Actor 的行为决定了它如何响应不同的消息。在 Scala 中,您可以通过扩展 Actor 特质并实现 receive 方法来定义行为。

  • receive 方法是一个偏函数,用于将传入的消息匹配到特定操作。
  • 每个 Actor 都会逐条、按顺序处理消息,从而确保其内部状态的线程安全。

ActorRef:Actor 的地址

您不会直接与 Actor 实例交互,而是向 ActorRef 发送消息。您可以将 ActorRef 理解为 Actor 的邮政地址。

  • 它是系统中代表某个特定 Actor 的句柄。
  • 发送到 ActorRef 的消息会被放入该 Actor 的邮箱。
  • 使用 actorOf 创建 Actor 时,您会获得一个 ActorRef。

向 Actor 发送消息

Actor 通信的主要方式是发送消息。最常见的消息发送方式是使用 !(读作“告知”)方法。

receiverActorRef ! "Your message here"

tell 方法是异步且发送后即忘的。它会发送消息,但不会等待回复。

让我们将创建 Actor 和向其发送消息结合起来:

import akka.actor.{Actor, ActorRef, Props, ActorSystem}

// 1. Define the actor's behavior
class GreeterActor extends Actor {
  def receive = {
    case "hello" => println(s"Greeter: Hello from ${self.path.name}!")
    case msg: String => println(s"Greeter: Received message: '$msg'")
    case _ => println("Greeter: Received something unexpected!")
  }
}

object SimpleActorApp {
  def main(args: Array[String]): Unit = {
    // 2. Create the ActorSystem
    val system = ActorSystem("GreeterSystem")

    // 3. Create a top-level actor and get its ActorRef
    val greeter: ActorRef = system.actorOf(Props[GreeterActor], "myGreeter")
    
    // 4. Send messages to the actor using '!'
    greeter ! "hello"
    greeter ! "How are you doing today?"
    greeter ! 123 // This will match the _ case

    // Give actors time to process messages, then terminate
    Thread.sleep(1000)
    system.terminate()
  }
}

创建子 Actor

Actor 可以创建其他 Actor,从而形成我们讨论过的层次结构。父 Actor 使用 context.actorOf 创建子 Actor。

  • context.actorOf:由 Actor 用于创建其子 Actor。
  • system.actorOf:由应用程序用于创建顶层(守护者)Actor。

创建子 Actor 有助于组织系统、委派任务并隔离故障。

父子通信

Actor 通过向彼此的 ActorRef 发送消息进行通信。子 Actor 可以通过 context.parent 获取其父 Actor 的 ActorRef。要回复消息的发送者,Actor 可以使用 sender()。

让我们看一个示例:父 Actor 创建子 Actor,告诉它执行工作,子 Actor 完成后报告结果:

import akka.actor.{Actor, ActorRef, Props, ActorSystem}
import scala.concurrent.ExecutionContext.Implicits.global

// Child Actor Definition: Does work and replies to sender
class ChildActor extends Actor {
  def receive = {
    case "work" =>
      println(s"ChildActor (${self.path.name}): Doing work from ${sender().path.name}")
      sender() ! "done" // Reply 'done' to the sender (parent)
  }
}

// Parent Actor Definition: Creates child, sends work, receives reply
class ParentActor extends Actor {
  // Create a child actor when the parent starts
  val child: ActorRef = context.actorOf(Props[ChildActor], "myChild")

  def receive = {
    case "start" =>
      println("ParentActor: Kicking off child's work.")
      child ! "work" // Tell the child to do 'work'
    case "done" =>
      println(s"ParentActor: Child ${sender().path.name} reported 'done'.")
      context.stop(child) // Stop the child actor
      context.stop(self)   // Stop the parent actor
  }
}

object HierarchyApp {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("HierarchySystem")
    val parent: ActorRef = system.actorOf(Props[ParentActor], "parentActor")
    parent ! "start" // Start the interaction

    // Wait for the system to terminate (actors will stop themselves)
    system.whenTerminated.onComplete(_ => println("ActorSystem terminated."))
  }
}

优雅地停止 Actor

不再需要 Actor 时,应当优雅地停止它们,以释放资源。您可以通过以下几种方式停止 Actor:

  • context.stop(self):Actor 停止自身。
  • context.stop(childRef):父 Actor 停止其一个子 Actor。
  • system.stop(actorRef):用于顶层 Actor,不过通常情况下,您会停止整个系统。

Actor 停止时,会先处理邮箱中的所有消息,然后终止。其子 Actor 也会递归停止。

快速检查:Actor 设计

请思考以下 Akka Actor 代码片段。如果 MyParentActor 是初始“请求”消息的发送者,那么 MyChildActor 向创建它的父级 MyParentActor 发回消息的正确方式是什么?

回顾:设计 Actor 系统

做得很好!在本课中,我们介绍了设计 Akka Actor 系统的关键方面:

  • Actor 按层次结构组织,这对于监管和系统结构至关重要。
  • ActorSystem 是应用程序使用 Akka 的入口点。
  • 您可以使用 receive 方法定义 Actor 的行为。
  • ActorRef 是发送消息所用的地址。
  • Actor 使用 !(告知)方法进行异步通信。
  • 父 Actor 使用 context.actorOf 创建子 Actor,子 Actor 可以使用 sender() 回复。
  • 可以使用 context.stop() 优雅地停止 Actor。

接下来,我们将深入了解 Akka 强大的监管策略,以及如何优雅地处理故障!

常见问题解答

「设计 Actor 系统」课时是免费的吗?

是的 — 「设计 Actor 系统」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 3 节课。

「设计 Actor 系统」这节课中我会学到什么?

学习设计并实现 Actor 层次结构、定义 Actor 行为,以及发送和接收消息。 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 3 节。

「设计 Actor 系统」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Akka Actor 模型基础
  2. 设计 Actor 系统
  3. 监管与容错
← 返回 Scala for Backend Engineering & Functional Programming