Akka集群分片:Entry演员可以有动态道具吗

编程入门 行业动态 更新时间:2024-10-12 01:30:05
本文介绍了Akka集群分片:Entry演员可以有动态道具吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

Akka群集共享看起来与用例非常匹配,我必须在Akka节点上创建有状态持久性参与者的单个实例。

Akka Cluster-Sharding looks like it matches well with a use case I have to create single instances of stateful persistent actors across Akka nodes.

我不清楚如果有可能具有需要参数进行构造的Entry actor类型。也许我需要重新考虑Entry actor如何获取此信息。

I'm not clear if it is possible though to have an Entry actor type that requires arguments to construct it. Or maybe I need to reconsider how the Entry actor gets this information.

Object Account { def apply(region: String, accountId: String): Props = Props(new Account(region, accountId)) } class Account(val region: String, val accountId: String) extends Actor with PersistentActor { ... }

而 ClusterSharding.start 使用一个Props实例创建所有Entry参与者。

Whereas the ClusterSharding.start takes in a single Props instance for creating all Entry actors.

来自 akka群集分片:

val counterRegion: ActorRef = ClusterSharding(system).start( typeName = "Counter", entryProps = Some(Props[Counter]), idExtractor = idExtractor, shardResolver = shardResolver)

然后根据您定义idExtractor的方式解析接收消息的Entry actor。从碎片的源代码可以看出,它使用ID作为给定Entry actor实例的名称:

And then it resolves the Entry actor that receives the message based on how you define the idExtractor. From the source code for shard it can be seen it uses the id as the name for a given Entry actor instance:

def getEntry(id: EntryId): ActorRef = { val name = URLEncoder.encode(id, "utf-8") context.child(name).getOrElse { log.debug("Starting entry [{}] in shard [{}]", id, shardId) val a = context.watch(context.actorOf(entryProps, name)) idByRef = idByRef.updated(a, id) refById = refById.updated(id, a) state = state.copy(state.entries + id) a }

}

似乎我应该让我的Entry actor人物代替通过给定的名称将其区域和accountId删除,尽管现在我确实会从字符串中解析出它而不是直接获取值,这确实让人感到有些疑惑。这是我最好的选择吗?

It seems I should instead have my Entry actor figure out its region and accountId by the name it is given, although this does feel a bit hacky now that I'll be parsing it out of a string instead of directly getting the values. Is this my best option?

推荐答案

我的处境与您非常相似。我没有确切的答案,但我可以与您和读者分享我的所作所为/尝试过的想法。

I am in a very similar situation as yours. I don't have an exact answer but I can share with you and the readers what I did/tried/thought.

选项1)如您所述,您可以提取您如何命名和解析路径的ID,碎片和区域信息。好处是 a)这很容易做到。 的缺点是a)Akka将actor路径编码为UTF-8,因此,如果您使用非标准网址字符(例如||或w / e)作为分隔符,则将需要首先从utf8对其进行解码。请注意,在Akka utf8内部是作为编码方法进行硬编码的,因此无法像在函数中那样提取编码格式,因此,如果明天进行Akka更改,您也必须改编您的代码。 b)您的系统不再保留同构(您的意思是感觉有点黑)。这意味着您增加了风险,有一天,数据可能包含信息分隔符字符串作为有意义的数据,并且系统可能会混乱。

Option 1) As you mentioned, you can extract id, shard and region information from how you name your stuff and parsing the path. The upside is a) that it's kind of easy to do. The downsides are that a) Akka encodes actor paths as UTF-8, so if you are using anything as a separator that is not a standard url character (such as || or w/e) you will need to first decode it from utf8. Note that inside Akka utf8 is hard-coded as encoding method, there is no way to extract the encoding format as in a function, so if tomorrow akka changes you'll have to adapt your code too. b) your system is not preserving homomorphism anymore (what you mean by "it feels kinda hacky"). Which implies that you are adding the risk that your data, one day, may contain your information separator string as meaningful data and your system may mess up.

选项2)分片如果不存在,将生成您的演员。因此,您可以强制您的代码始终将初始化消息发送给未初始化的参与者,其中包含构造函数参数。您的分片演员会在其中包含以下内容:

Option 2) Sharding will spawn your actor if it doesn't exist. So you can force your code to always send an init message to non initialized actors, which contains your constructor parameters. Your sharded actors will have something inside of them of the kind:

val par1: Option[param1Type] = None def receive = { case init(par1value) => par1 = Some(par1value) case query(par1) => sender ! par1 }

从您的区域访问参与者中,您始终可以先发送查询消息,然后如果返回为None,则返回init消息。这假定您的区域访问角色没有保留已初始化角色的列表,在这种情况下,您可以使用init生成,然后正常使用它们。 好​​处是a)优雅的b)感觉不错

And from your region access actor you can always send first the query message and then the init message if the return is None. This assumes that your region access actor does not mantain a list of the initialized actors, in which case you can just spawn with init and then use them normally. The upside is a) It's elegant b) it "feels" right

缺点:a)它需要2封邮件(如果您(不要保留已初始化的参与者的列表)

Downside: a) it takes 2x messages (if you don't maintain a list of initialized actors)

选项3) 该选项已经过测试,无法正常工作。我会把它留给人们,以避免浪费时间尝试同样的事情。 我不知道这是否可行,我还没有测试过,因为我在不允许有特殊约束和花哨的东西来制作^ _ ^但是请随时尝试,并请在下午或评论中告诉我! 基本上,您可以通过以下方式开始您的区域

Option 3) THIS OPTION HAS BEEN TESTED AND DOESN'T WORK. I'll just leave it here for people to avoid wasting time trying the same. I have no idea if this works, I haven't tested because I'm using this scenario in production with special constraints and fancy stuff is not allowed ^_^ But feel free to try and please let me know with a pm or comment! Basically, you start your region with

val counterRegion: ActorRef = ClusterSharding(system).start( typeName = "Counter", entryProps = Some(Props[Counter]), idExtractor = idExtractor, shardResolver = shardResolver)

如果您在您所在地区的创作演员中执行以下操作:

What if you, in your region creation actor, do something like:

var providedPar1 = v1 def providePar1 = providedPar1 val counterRegion: ActorRef = ClusterSharding(system).start( typeName = "Counter", entryProps = Some(Props(classOf[Counter], providePar1), idExtractor = idExtractor, shardResolver = shardResolver)

然后为每个创建更改providerPar1的值吗?它的缺点是,在可行的选项中,您需要避免更改providerPar1的值,直到您100%确保角色已创建,否则您可能会冒险访问新的,错误的价值(是的,竞赛条件!)

And then you change the value of providedPar1 for each creation? The downside of this is that, in the option it works, you'd need to avoid changing the value of providedPar1 until you are 100% sure that the actor has been created, or you may risk it accessing the new, wrong value (yay, race conditions!)

通常,使用选项2恕我直言会更好,但在大多数情况下,选项1带来的风险很小,您可以减轻风险适当地考虑了简单性(和性能)的优势。

In general you are better off with option 2 imho, but in most scenarios the risks introduced by 1 are small and you can mitigate them properly given the simplicity (and performance) advantages.

希望这个咆哮有帮助,如果您尝试3种方法,请告诉我!

Hope this rant helps, let me know if you try 3 out how it works!

更多推荐

Akka集群分片:Entry演员可以有动态道具吗

本文发布于:2023-11-25 10:58:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1629480.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:集群   道具   分片   演员   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!