Akka actor跨JVM和服务器进行扩展,例如akka.io [英] Akka actors scaling across JVM's and servers, and example at akka.io

查看:88
本文介绍了Akka actor跨JVM和服务器进行扩展,例如akka.io的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现Akka着陆页上提供的介绍性 Akka远程处理示例有点难以理解,以及学习出于介绍目的而处理远程结构错误的来龙去脉所需的文档长度。



以下是上述示例中的代码,我想要求在一个公平的上下文中描述该代码的含义,同时涉及是否可以仅通过更改配置就可以远程向任何参与者发送消息的问题。关于最后一点的先前答案似乎与当前的Akka文档有些矛盾,而该文档

  // -------------- ---------------- 
//在所有计算机上配置
akka {
actor {
provider = akka.remote.RemoteActorRefProvider
部署{
/ greeter {
remote = akka.tcp:// MySystem @ machine1:2552
}
}
}
}

// ------------------------------
//定义问候演员和问候消息
案例类Greeting(谁:字符串)扩展了可序列化的

类GreetingActor扩展了具有ActorLogging的Actor {
def接收= {
案例Greeting(谁)⇒ log.info( Hello + who)
}
}

// -------------------- ----------
//在机器1上:空系统,部署目标从机器2
val system = ActorSystem( MySystem)

// ------------------------ ------
//在机器2上:远程部署-在machine1上部署
val system = ActorSystem( MySystem)
val greeter = system.actorOf(Props [GreetingActor] ,name = greeter)

// ------------------------------
//在机器3上:远程查找( greeter的逻辑位置是machine2,远程部署是透明的)
val system = ActorSystem( MySystem)
val greeter = system.actorSelection( akka .tcp:// MySystem @ machine2:2552 / user / greeter)
greeter! Greeting( Sonny Rollins)

因此,此示例代码的介绍性解释也照顾了上述关键方面将非常有帮助。一种解释应该有望使选择一种Actor体系结构,该体系结构可以轻松地在单个JVM内以及跨JVM和服务器边界进行扩展,而不是连续数天进入实验模式。



<谢谢!

解决方案

这可能最容易解释您从下至上发布的示例。最后,它显示了原始位置的透明性,可在不对位置字符串进行硬编码的情况下获得演员参考。经过较小的修改,我们得到:

  // ----------------- ------------- 
//在机器3上:远程查找( greeter的逻辑位置是machine2,远程部署是透明的)
val system = ActorSystem( MySystem)
val greeter = system.actorSelection(uri)//其中uri来自配置文件或某个目录
greeter! Greeting( Sonny Rollins)

如何从配置中查找角色的位置,显示在< a href = https://stackoverflow.com/questions/9125142/can-a-lookup-an-akka-actor-address-from-configuration?rq=1>是否可以从配置中查找akka actor地址?总结使用角色的位置透明性。从uri的选择中获取ActorRef后,您无需知道它是本地演员还是远程演员,您只需向其发送消息即可。



将示例向上移动一点:

  / / ------------------------------ 
//在计算机2上:远程部署-在machine1 $ b $上部署b val system = ActorSystem( MySystem)
val greeter = system.actorOf(Props [GreetingActor],name = greeter)

这里是演示部署角色的本地透明性的地方。 actorOf 是工厂实例化而不是查找,因此是部署。 name属性将其部署到 / user / greeter的uri路径。如果您具有单个jvm配置(例如,空配置)并在单个进程中运行该配置,则可以将本地actor部署到单个jvm中。然而示例注释表明它在machine2上运行并部署到machine1中。这是因为每个jvm的配置都位于文件的更上方:

  akka {
actor {
provider = akka.remote.RemoteActorRefProvider
部署{
/ greeter {
remote = akka.tcp:// MySystem @ machine1:2552
}
}
}
}

也就是说用户空间 / user / greeter 将使用RemoteActorRefProvider远程部署到machine1上的actor系统MySystem上。如果取出该配置,则要部署的示例代码将不会进行远程部署,而将进行本地部署。如果是本地部署,则可以使用本地路径查找它,而没有完整的uri指向实际部署到的系统。无论是本地部署还是远程部署,您都将获取ActorRef并向其发送消息。



在以下位置进一步移动文件:

  //- ----------------------------- 
//在机器1上:空系统,目标是从机器2 $ b进行部署$ b val system = ActorSystem( MySystem)

这只是告诉您是否已配置它将把在 greeter位置的actor远程部署到machine1上的 MySystem,然后您应该在machine1上启动一个名称与配置匹配的actor系统。如果没有,您将在尝试从其他计算机部署或解决迎接者时遇到连接或查找错误。



最后,演员本身是位置透明的,因为它与位置无关,如图所示:

  // ------------------------------ 
//定义问候语演员和问候消息
案例类Greeting(谁:字符串)扩展了可序列化的

类GreetingActor扩展了ActorLogging的Actor {
def receive = {
案例Greeting(who )⇒log.info( Hello + who)
}
}

因此,该actor不知道它是本地actor还是远程actor,或者正在使用akka Testkit在单元测试中运行。实际上,显示在所有计算机中部署的配置文件正在修改参与者系统的工厂行为,以将其问候部署到一台计算机中。


I find the introductory example of Akka remoting supplied on the Akka landing page a bit hard to swallow as an introduction, and the length of documentation necessary for learning the ins and outs of remoting malstructured for introductory purposes.

Here below is the code from the mentioned example, and I'd like to ask for a delineation of what that code means with some fair context, while relating to the question of whether any actor can be messaged remotely as if it were local requiring only a mere change of configuration. Previous answers about this last bit may seem somewhat contradictory to current Akka documentation, whereas the documentation in itself is somewhat inconclusive about this very point.

// ------------------------------
// config on all machines
akka {
 actor {
   provider = akka.remote.RemoteActorRefProvider
   deployment {
     /greeter {
       remote = akka.tcp://MySystem@machine1:2552
     }
   }
 }
}

// ------------------------------
// define the greeting actor and the greeting message
case class Greeting(who: String) extends Serializable

class GreetingActor extends Actor with ActorLogging {
  def receive = {
    case Greeting(who) ⇒ log.info("Hello " + who)
  }
}

// ------------------------------
// on machine 1: empty system, target for deployment from machine 2
val system = ActorSystem("MySystem")

// ------------------------------
// on machine 2: Remote Deployment - deploying on machine1
val system = ActorSystem("MySystem")
val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

// ------------------------------
// on machine 3: Remote Lookup (logical home of "greeter" is machine2, remote deployment is transparent)
val system = ActorSystem("MySystem")
val greeter = system.actorSelection("akka.tcp://MySystem@machine2:2552/user/greeter")
greeter ! Greeting("Sonny Rollins")

So an introductory explanation of this example code that also takes care of the key aspects mentioned above would be very helpful. An explanation that should hopefully enable picking an actors architecture that can easily scale within a single JVM and across JVM's and server boundaries, rather than going into experimentation mode for days if not more.

Thanks!

解决方案

Its probably easiest to explain the example you posted from bottom to top. At the end it shows vanilla location transparency to get an actor ref where we wouldn't hardcode the location string. With that minor modification we get:

// ------------------------------
// on machine 3: Remote Lookup (logical home of "greeter" is machine2, remote deployment is transparent)
val system = ActorSystem("MySystem")
val greeter = system.actorSelection(uri) // where uri is from config or some directory
greeter ! Greeting("Sonny Rollins")

How to lookup the location of an actor from configuration is shown at can a lookup an akka actor address from configuration? which sums up location transparency of using an actor. Once you have the ActorRef from the selection by uri you don't need to know whether its a local or a remote actor you can just message it.

Moving up the example the bit where it says:

// ------------------------------
// on machine 2: Remote Deployment - deploying on machine1
val system = ActorSystem("MySystem")
val greeter = system.actorOf(Props[GreetingActor], name = "greeter")

this is there to demonstrate local transparency of deploying an actor. The actorOf is a factory instantiation rather than a lookup hence it is a deployment. The name property deploys it to a uri path of "/user/greeter". If you had a single jvm configuration (e.g. empty configuration) and ran that in a single process you would get an local actor deployed into the single jvm. Yet the example comment says its running on machine2 and deploying into machine1; this is because of the config at each jvm which is further up the file:

akka {
 actor {
   provider = akka.remote.RemoteActorRefProvider
   deployment {
     /greeter {
       remote = akka.tcp://MySystem@machine1:2552
     }
   }
 }
}

That is saying that the user space "/user/greeter" is going to use RemoteActorRefProvider to remote deploy onto the actor system MySystem on machine1. If you took out that config then the sample code to deploy would not remote deploy but would local deploy. If it was a local deploy you could look it up using a local path without the full uri pointing to the system it is actually deployed onto. Regardless of whether its a local or remote deploy you get an ActorRef and message it.

Moving up the file some more at:

// ------------------------------
// on machine 1: empty system, target for deployment from machine 2
val system = ActorSystem("MySystem")

that is simply telling you that if you have config which will remote deploy actors at location "greeter" into "MySystem" on machine1 then you should start an actor system on machine1 with a name which matches the config. If not you will get connection or lookup errors trying to deploy or resolve "greeter" from other machines.

Finally the actor itself is location transparent as it has nothing about location baked into it as shown by:

// ------------------------------
// define the greeting actor and the greeting message
case class Greeting(who: String) extends Serializable

class GreetingActor extends Actor with ActorLogging {
  def receive = {
    case Greeting(who) ⇒ log.info("Hello " + who)
  }
}

So that actor has no idea whether it is a local actor or a remote actor or is running in a unit test using the akka Testkit. Effectively the configuration file shown deployed in all the machines is modifying the factory behaviours of the actor systems to deploy into the location "greeter" into one machine.

这篇关于Akka actor跨JVM和服务器进行扩展,例如akka.io的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆