如何动态创建远程actor并使用AKKA控制它们

时间:2013-09-14 05:10:39

标签: scala akka distributed

我想要做的是:

1)在服务器上创建一个主actor,可以在10个不同的机器上动态创建10个远程actor

2)主演员将任务分配给10个远程演员

3)当每个远程演员完成他们的工作时,他们将结果发送给主演员

4)主人关闭整个系统

我的问题是:

1)我不确定如何配置主演员,下面是我的服务器部件代码:

class MasterAppliation extends Bootable{
    val hostname = InetAddress.getLocalHost.getHostName
    val config = ConfigFactory.parseString(
          s"""
            akka{
            actor{
                provider = "akka.remote.RemoteActorRefProvider"
                deployment {
                    /remotemaster {
                        router = "round-robin"
                        nr-of-instances = 10
                        target {
                            nodes = ["akka.tcp://remotesys@host1:2552", "akka.tcp://remotesys@host2:2552", ....... akka.tcp://remotesys@host10:2552"]
                        }
                }
            }
            remote{
                enabled-transports = ["akka.remote.netty.tcp"]
                netty.tcp{
                hostname = "$hostname"
                port = 2552
                }
            }     
          }""")

    val system = ActorSystem("master", ConfigFactory.load(config))        
    val master = system.actorOf(Props(new master), name = "master") 
    def dosomething = master ! Begin()
    def startup() {}
    def shutdown() {
        system.shutdown()
    }
}

class master extends Actor {   
   val addresses = for(i <- 1 to 10) 
       yield AddressFromURIString(s"akka://remostsys@host$i:2552")

   val routerRemote = context.actorOf(Props[RemoteMaster].withRouter(
           RemoteRouterConfig(RoundRobinRouter(12), addresses)))

   def receive = {
     case Begin=>{
       for(i <- 1 to 10) routerRemote ! Work(.....)     
     }
     case Result(root) ........      
   }
}


object project1 {
  def main(args: Array[String]) {                
    new MasterAppliation
  }
}

2)我不知道如何在远程客户端上创建远程actor。我看了this tutorial。我需要 编写类似于服务器部分的客户端部分,这意味着我需要创建一个负责创建远程actor的对象?但这也意味着当我运行客户端部分时,已经创建了远程actor!我真的很困惑。

3)我不知道如何关闭整个系统。在上面的教程中,我发现有一个名为shutdown()的函数,但我从未见过有人调用它。

这是我第一次在Scala和AKKA中编写分布式程序。所以我真的需要你的帮助。 非常感谢。

1 个答案:

答案 0 :(得分:6)

第一次设置整个过程是一件痛苦的事情,但如果你这样做,你将会有一个好的骨架,你会定期使用它。

我已在评论中写下了用户群集未进行远程处理的问题。

我是这样做的: 我建立了一个包含三个子项目的sbt根项目。

  • 常见
  • 前端
  • 后端

common中,您放置了两个项目共有的所有内容,例如它们共享的消息,在前端创建并部署到后端的actor类。

reference.conf放入公共项目,这是我的:

akka {
loglevel = INFO
actor {
    provider = "akka.cluster.ClusterActorRefProvider"
    debug {
        lifecycle = on
    }
}

 cluster {
      seed-nodes = [
        "akka.tcp://application@127.0.0.1:2558",
        "akka.tcp://application@127.0.0.1:2559"
      ]
  }

}

现在在前端:

akka {


    remote {
        log-remote-lifecycle-events = off
        netty.tcp {
            hostname = "127.0.0.1"
            port = 2558
        }
    }

    cluster {
      auto-down = on
      roles = [frontend]
    }
}

和后端

akka {

    remote {
        log-remote-lifecycle-events = off
        netty.tcp {
            hostname = "127.0.0.1"
            port = 0
        }
    }

    cluster {
      auto-down = on
      roles = [backend]
    }
}

这将是这样的: 首先启动前端部分,它将控制集群。 然后你可以启动你想要的任何数量的自动加入的后端(查看端口,它是0,因此它将被随机选择)。

现在您需要将整个逻辑添加到前端main: 创建名为application的actor系统:

val system = ActorSystem("application")

在后端主处做同样的事。

现在在前端编写代码,这样就可以使用路由器创建工作人员,这是我的示例代码:

context.actorOf(ServiceRuntimeActor.props(serviceName)
        .withRouter(
          ClusterRouterConfig(ConsistentHashingRouter(),
            ClusterRouterSettings(
              totalInstances = 10, maxInstancesPerNode = 3,
            allowLocalRoutees = false, useRole = Some("backend"))
          )
        ),
        name = shortServiceName)

只需将您的ServiceRuntimeActor更改为您的工作人员的姓名即可。它会将工作人员部署到您已启动的所有后端,并将其限制为每个节点最多3个,最多10个。

希望这会有所帮助。