【问题标题】:Listening to a remote akka ActorSystem's log stream监听远程 akka ActorSystem 的日志流
【发布时间】:2015-06-19 12:20:32
【问题描述】:

我正在尝试订阅远程 akka ActorSystem 的日志流,基本上是为了编写一个控制台来显示远程 Actor 的运行日志。

我能想到的唯一方法是:在日志 ActorSystem 中创建一个 Actor,让该 Actor 订阅 ActorSystem.eventStream,然后在我的控制台的 ActorSystem 中使用 actorSelection 订阅该 Actor。

但这似乎很“间接”,因为日志管道看起来像:

logging Actor --> eventStream --> Actor subscribed to eventStream --> local Actor

有没有更简单的方法来订阅事件流?

【问题讨论】:

    标签: scala logging akka actor akka-remote-actor


    【解决方案1】:

    从简单的角度来看,没有什么可以禁止您在没有其他参与者的情况下将远程参与者订阅到您的事件流。 Akka documentation 提到:

    事件流是本地设施,这意味着它不会 将事件分发到集群环境中的其他节点(除非 显式订阅远程 Actor 到流)。如果你需要 在 Akka 集群中广播事件,而不知道你的接收者 明确地(即获取他们的 ActorRefs),你可能想看看 进入:集群中的分布式发布订阅。

    出于说明目的,请考虑以下与您要订阅的远程系统相对应的代码片段:

      class PublisherActor extends Actor with ActorLogging { // example publisher actor just to generate some logs
        context.system.scheduler.schedule(1.second, 1.second, self, "echo")
        def receive = {
          case "echo" ⇒
            val x = Random.nextInt(100)
            log.info(s"I got a random number: $x")
        }
      }
    
      def runPublisher() = {
        println("=== running publisher node ===")
        val system = ActorSystem("PublisherSystem")
        val selection = system.actorSelection("akka.tcp://SubscriberSystem@127.0.0.1:2553/user/subscriber")
        selection.resolveOne(10.seconds) onSuccess { // when the listener actor is available,
          case listener ⇒ system.eventStream.subscribe(listener, classOf[LogEvent]) // subscribe it to the event stream
        }
        val publisher = system.actorOf(Props[PublisherActor], "publisher") // some example publisher
      }
    

    然后是“本地”节点中的相应订阅者,从那里您要显示日志:

      class SubscriberActor extends Actor with ActorLogging {
        log.info("subscriber listening...")
        def receive = {
          case msg ⇒ log.info(s"Got: $msg")
        }
      }
    
      def runSubscriber() = {
        println("=== running subscriber node ===")
        val system = ActorSystem("SubscriberSystem")
        val listener = system.actorOf(Props[SubscriberActor], "subscriber")
      }
    

    但是,此解决方案有几个注意事项,因为发布者必须在订阅者之前运行(或者订阅者在发布者启动之前实施一些重试策略),位置是硬编码的等等。如果您想拥有一个更健壮、更有弹性的系统并且这是允许的,请遵循文档中的建议,并在集群环境中使用 distributed publisher-subscriber,这具有类似数量的样板文件的几个优势。

    希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      • 2014-02-21
      • 2021-01-27
      • 2022-01-01
      • 1970-01-01
      • 2012-03-08
      • 2017-03-16
      相关资源
      最近更新 更多