• AKKA Actor创建


    Actor 类定义 

    Actor 类需要继承AbstractActor

    实现createReceive方法,绑定各类actor收到不同类型消息对应处理不同业务逻辑

    默认提供了ReceiveBuilder类辅助创建 Receive

    对actorOf的调用返回ActorRef的实例。这是 Actor 实例的句柄,也是与之交互的唯一方法。

    ActorRef是不可变的,并且与它所表示的 Actor 有一对一的关系。ActorRef也是可序列化的, 序列化通过网络发送它,并在远程主机上使用它,并且它仍然在网络上表示原始节点上的同一个 Actor。

    Actor的层级关系

    Actor的层级关系类似树模式

    谁创建谁管理原则:

    ActorSystem 创建就由ActorSystem负责监控管理(重启,异常,恢复等)
    Actor中创建另外的Actor,则创建者看做为父级,负责监控管理它创建出来的actor

     Actor 生命周期

     actorOf -> preStart -> start -> receive -> stop -> postStop

    另外:

    reRestart()默认行为是在重启(restarting)之前,它会终止所有的children actors(这个过程是递归的)。postRestart()则发生在重启成功之后。当然,方法都可以重写这两个方法以改变其行为。

    Props 

    Props 创建 Actor 的配置选项,推荐在actor类提供一个通用的props方法来创建

    注意:

    1,同一个akka集群中创建的actor 实例 name不能重复,不然会报InvalidActorNameException异常

    2,ActorSytem同一个集群,各节点的ActorSytem name必须相同

    3,不允许自行new创建actor实例
    如果直接new Actor实例方式创建Actor会报ActorInitializationException错误

    示例:

    <!-- Gradle -->
    dependencies {
      compile group: 'com.typesafe.akka', name: 'akka-actor_2.12', version: '2.5.21'
    }
    package akka.demo.actor
    
    import akka.actor.AbstractActor
    import akka.actor.ActorRef
    
    import akka.actor.Props
    import akka.japi.pf.ReceiveBuilder
    import org.slf4j.LoggerFactory
    
    /**
     ** created by tankx
     ** 2019/9/10
     **/
    class HelloActor(val name: String) : AbstractActor() {
    
      //创建子actor
      private val childActor: ActorRef = context.actorOf(ChildActor.props())
    
      companion object {
        private val log = LoggerFactory.getLogger(HelloActor::class.java)
       //提供静态通用对外的props  
        fun props(name: String): Props {
          //return Props.create(HelloActor::class.java, name)//默认方式
          return Props.create(HelloActor::class.java) {
            HelloActor(name)
          }
        }
      }
    
      override fun preStart() {
        log.info("preStart")
        super.preStart()
      }
    
      override fun postStop() {
        log.info("postStop")
        super.postStop()
      }
    
      override fun createReceive(): Receive {
        return ReceiveBuilder.create().matchAny(::onReceive).build()
      }
    
      fun onReceive(msg: Any) {
    
        log.info("$name say: $msg")
        log.info("sender:{}", sender.toString())
    
    
      }
    
    }
    package akka.demo.actor
    
    import akka.actor.AbstractActor
    
    import akka.actor.Props
    import akka.japi.pf.ReceiveBuilder
    import org.slf4j.LoggerFactory
    
    /**
     ** created by tankx
     ** 2019/9/10
     **/
    class ChildActor : AbstractActor() {
    
      private val log = LoggerFactory.getLogger(ChildActor::class.java)
    
      companion object {
        fun props(): Props {
          return Props.create(ChildActor::class.java)
        }
      }
    
      override fun preStart() {
        log.info("preStart")
        super.preStart()
      }
    
      override fun postStop() {
        log.info("postStop")
        super.postStop()
      }
    
      override fun createReceive(): Receive {
        return ReceiveBuilder.create().matchAny(::onReceive).build()
      }
    
      fun onReceive(msg: Any) {
        log.info("onReceive: $msg")
      }
    
    }

     创建ACTOR,并发消息

    val system = ActorSystem.create("akka-system")
    
    val actorRef = system.actorOf(HelloActor.props("aa"), HelloActor::class.java.simpleName)
    
    actorRef.tell("hi world", ActorRef.noSender()) //给actor发消息

     依赖注入

    如果有依赖注入的情况,需要传入依赖项来构建Actor

    示例:

    package akka.demo.actor
    
    import akka.actor.Actor
    import akka.actor.IndirectActorProducer
    
    /**
     ** created by tankx
     ** 2019/9/11
     ** 如果有依赖注入方式可使用当前的工厂类的方式进行创建actor
     **/
    class ActorFactory(var applicationContext: String) : IndirectActorProducer {
    
    
      override fun actorClass(): Class<out Actor> {
        return HelloActor::class.java
      }
    
      override fun produce(): Actor {
        return HelloActor(applicationContext)
      }
    
    
    }

    创建方式:

    val actorFactoryRef = system.actorOf(Props.create(ActorFactory::class.java, "aaa"), "aaa")
      actorFactoryRef.tell("hi factory", ActorRef.noSender())

    总结:

     AKKA创建Actor需要严格按照推荐的方式去创建,以避免破坏Actor 封装。

  • 相关阅读:
    asp.net 文件下载
    net 数据库连接详解 相当经典啊
    取值:webconfig中的key
    通过监听的端口查找本机进程和服务思路
    以系统服务运行某个程序
    测底根除Windows流氓软件开机自动运行
    使用Wireshark在主机上抓取远程主机的数据流量
    记录Windows远程登录日志
    证书不匹配发出告警的解决方法
    WPS office云同步图标彻底删除方法
  • 原文地址:https://www.cnblogs.com/tankaixiong/p/11511251.html
Copyright © 2020-2023  润新知