识别和处理 Akka 中闲置参与者的最佳实践
Best practice to identify and deal with idle actors in Akka
我是 Akka 框架的新手,我正在用它构建一个群聊应用程序。我的应用程序可能有 1000 万个相同类型的 actor 实例(每个群聊一个 actor 实例),其中只有 5% 是高活跃的,而其中 60% 可以闲置(没有收到任何消息)几天。
我想知道:
- 有什么最佳做法可以识别这些无所事事的参与者吗?
- 处理它们的最佳做法是什么?阻止他们就够了吗?
- 是否有识别这些闲置参与者的最佳实践?
唯一的办法就是让每个actor保持上次激活的时间。然后,为了加快对最长非活动参与者的调查,您可以组织一个类似索引的结构,例如优先队列。然后,一个专门的 actor 会定期唤醒并从空闲时间超过某个预定义时间段的 actor 中清除该结构。
- 处理它们的最佳做法是什么?阻止他们就够了吗?
一个空闲的actor除了核心内存之外不消耗任何资源。如果您有足够的内存,最好的做法是什么都不做。如果您想保存该内存,请将 actor 存储在数据库中(在一段时间不活动后),然后按需从那里读取它。
Is there any best practice to identify these idle actors?
一个演员的 ActorContext
有一个 setReceiveTimeout
方法来定义演员的不活动阈值:如果演员在给定的时间内没有收到消息,那么 akka.actor.ReceiveTimeout
消息被发送给演员。例如:
import akka.actor.{ Actor, ReceiveTimeout }
import scala.concurrent.duration._
class ChatActor extends Actor {
context.setReceiveTimeout(2 hours)
def receive = {
case ReceiveTimeout =>
// do something
// other case clauses
}
}
上面的ChatActor
如果两个小时没收到消息就会收到ReceiveTimeout
消息。 (但是,如文档所述:"the receive timeout might fire and enqueue the ReceiveTimeout
message right after another message was enqueued; hence it is not guaranteed that upon reception of the receive timeout there must have been an idle period beforehand as configured via this method.")
What is the best practice to deal with them?
停止不活跃的演员是个好主意;否则你可能会发生内存泄漏。以下是阻止这些参与者的一些方法:
- 不活动的 actor 抛出异常,该异常在 actor 的父级中定义的 supervisor strategy 中处理。在主管策略中,父级停止空闲角色(例如,通过
context stop sender()
)。
- 不活动的 actor 将其
self
引用发送到一个 "reaper" actor,该 actor 收集对空闲 actor 的引用并定期剔除(即停止)这些 actor(可能使用 scheduler).
- 不活动的 actor 自行停止(通过
context stop self
)。
已找到有关停止 actors 的更多信息 here。
Is stopping them enough?
当一个 actor 停止时,它的 ActorRef
本质上变得无效。来自 documentation:
After stopping an actor, its postStop
hook is called, which may be used e.g. for deregistering this actor from other services. This hook is guaranteed to run after message queuing has been disabled for this actor, i.e. messages sent to a stopped actor will be redirected to the deadLetters
of the ActorSystem
.
此时,现在过时的 ActorRef
指向的底层 actor 实例符合垃圾收集条件。换句话说,必须停止 actor 才能使其有资格进行垃圾收集。因此,关于释放内存,停止 actor 就足够了。您还可以在 actor 停止后删除无效的 ActorRef
本身。请注意 removing an ActorRef
不会自动停止 actor:
It is important to note that Actors do not stop automatically when no longer referenced, every Actor that is created must also explicitly be destroyed.
我是 Akka 框架的新手,我正在用它构建一个群聊应用程序。我的应用程序可能有 1000 万个相同类型的 actor 实例(每个群聊一个 actor 实例),其中只有 5% 是高活跃的,而其中 60% 可以闲置(没有收到任何消息)几天。
我想知道:
- 有什么最佳做法可以识别这些无所事事的参与者吗?
- 处理它们的最佳做法是什么?阻止他们就够了吗?
- 是否有识别这些闲置参与者的最佳实践?
唯一的办法就是让每个actor保持上次激活的时间。然后,为了加快对最长非活动参与者的调查,您可以组织一个类似索引的结构,例如优先队列。然后,一个专门的 actor 会定期唤醒并从空闲时间超过某个预定义时间段的 actor 中清除该结构。
- 处理它们的最佳做法是什么?阻止他们就够了吗?
一个空闲的actor除了核心内存之外不消耗任何资源。如果您有足够的内存,最好的做法是什么都不做。如果您想保存该内存,请将 actor 存储在数据库中(在一段时间不活动后),然后按需从那里读取它。
Is there any best practice to identify these idle actors?
一个演员的 ActorContext
有一个 setReceiveTimeout
方法来定义演员的不活动阈值:如果演员在给定的时间内没有收到消息,那么 akka.actor.ReceiveTimeout
消息被发送给演员。例如:
import akka.actor.{ Actor, ReceiveTimeout }
import scala.concurrent.duration._
class ChatActor extends Actor {
context.setReceiveTimeout(2 hours)
def receive = {
case ReceiveTimeout =>
// do something
// other case clauses
}
}
上面的ChatActor
如果两个小时没收到消息就会收到ReceiveTimeout
消息。 (但是,如文档所述:"the receive timeout might fire and enqueue the ReceiveTimeout
message right after another message was enqueued; hence it is not guaranteed that upon reception of the receive timeout there must have been an idle period beforehand as configured via this method.")
What is the best practice to deal with them?
停止不活跃的演员是个好主意;否则你可能会发生内存泄漏。以下是阻止这些参与者的一些方法:
- 不活动的 actor 抛出异常,该异常在 actor 的父级中定义的 supervisor strategy 中处理。在主管策略中,父级停止空闲角色(例如,通过
context stop sender()
)。 - 不活动的 actor 将其
self
引用发送到一个 "reaper" actor,该 actor 收集对空闲 actor 的引用并定期剔除(即停止)这些 actor(可能使用 scheduler). - 不活动的 actor 自行停止(通过
context stop self
)。
已找到有关停止 actors 的更多信息 here。
Is stopping them enough?
当一个 actor 停止时,它的 ActorRef
本质上变得无效。来自 documentation:
After stopping an actor, its
postStop
hook is called, which may be used e.g. for deregistering this actor from other services. This hook is guaranteed to run after message queuing has been disabled for this actor, i.e. messages sent to a stopped actor will be redirected to thedeadLetters
of theActorSystem
.
此时,现在过时的 ActorRef
指向的底层 actor 实例符合垃圾收集条件。换句话说,必须停止 actor 才能使其有资格进行垃圾收集。因此,关于释放内存,停止 actor 就足够了。您还可以在 actor 停止后删除无效的 ActorRef
本身。请注意 removing an ActorRef
不会自动停止 actor:
It is important to note that Actors do not stop automatically when no longer referenced, every Actor that is created must also explicitly be destroyed.