我想阅读ShardRegions邮箱中的邮件。在以前的akka版本中,我们可以使用以下代码来获取邮箱的大小:
getContext().getMailboxSize();
有没有办法获取邮箱中的邮件类型?
答案 0 :(得分:4)
这是解决方案
为分片区域定义包装邮箱,如下所示:
class UnboundedMailboxWrapper extends MailboxType with ProducesMessageQueue[UnboundedMailboxWrapper.MessageQueue] {
def this(settings: ActorSystem.Settings, config: Config) = this()
final override def create(owner: Option[ActorRef], system: Option[ActorSystem]): MessageQueue =
new UnboundedMailboxWrapper.MessageQueue
}
object UnboundedMailboxWrapper {
class MessageQueue extends ConcurrentLinkedQueue[Envelope] with UnboundedQueueBasedMessageQueue {
val runtime = RuntimeManager.runtime
final def queue: Queue[Envelope] = this
override def enqueue(receiver: ActorRef, handle: Envelope): Unit = {
runtime.queue.add(handle)
queue add handle
}
override def dequeue(): Envelope = {
if (!runtime.queue.isEmpty) runtime.mailbox.queue.poll()
queue.poll()
}
}
}
在这个邮箱中我们将添加的元素复制到另一个队列,因此在计算大小和其他操作时,对邮箱队列的性能没有任何影响
在重复队列中,我们可以计算消息数量并对其进行排序:
def getElemets(): String = {
runtime.queue.asScala.toList.groupBy(_.message.getClass.getName)
.map(e ⇒ (e._1, e._2.length)).toSeq
.sortBy(_._2).foldLeft("") { (a, b) ⇒
b._1 + ":" + b._2 + "\n" + a
}
}
使用JMX或任何其他方式我们可以在运行时调用此方法
并将此邮箱分配给ShardRegion调度程序:
monit-dispatcher {
mailbox-type = "im.actor.server.cluster.UnboundedMailboxWrapper"
}
akka.cluster.sharding {
use-dispatcher = "monit-dispatcher"
}