Akka群集关于动态创建执行元的基本说明

oymdgrw7  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(158)

在Akka remote中,我们通过在actor系统配置中定义actor来创建actor,或者通过编程方式说出其他actor系统位置。
我们通过创建的引用向参与者发送消息,或者我们可以通过获取actorselection来获取参与者引用。
但是,对于 akka 星团,我没有明确的观点。
我们如何在集群外动态创建参与者?
我们如何向参与者发送消息,以及参与者如何跨集群创建消息(分布式)?
或者,我们必须发送集群中的特定参与者,这将创建参与者或分发消息?

nfs0ujit

nfs0ujit1#

  • 已编辑答案,用于回答未回答的问题。*
    一般方法

建议将此方法用于更一般的使用情况。
Q1:我们如何在集群外部动态创建参与者?
您无法直接在群集内或群集外的其他成员中创建执行元。但是,您可以在应用程序逻辑中实现成员创建。然后,您可以在主管级别执行元中订阅群集成员资格事件。请参阅文档
假设您订阅了MemberUp事件以检测群集中的新成员,订阅了MemberRemoved事件以检测脱机成员。因此,您可以在每个执行元系统中维护一个路由表,以便与群集中的其他执行元系统进行通信。

cluster.subscribe(
                 getSelf(), ClusterEvent.initialStateAsEvents(),
                 ClusterEvent.MemberUp.class,
                 ClusterEvent.MemberRemoved.class );

然后,您可以从成员资格事件中获取成员地址,并实现其他应用程序逻辑。

@Override
        public Receive createReceive() {
            return receiveBuilder()
                    .match(ClusterEvent.MemberUp.class, memberUp -> {
                        // update routing table                        
                        // implement your logic when member is up
                    }).match(ClusterEvent.MemberRemoved.class, memberUp -> {
                        // update routing table                        
                        // implement your logic when member is up
                    }).build();
        }

问题2:我们如何向参与者发送消息,以及参与者如何跨群集创建消息
由于您的路由表中有参与者地址,因此可以使用Akka远程处理向它们发送消息。
对于在集群中动态创建参与者并与之通信的更多分布式方法,可以使用Cluster Singleton和/或Cluster Sharding。

群集单独

如果群集中只需要一个特定类型的执行元,则可以创建群集单元集。无论群集中有多少成员,此执行元都将始终在群集中的某个位置可用/运行。
Q1:我们如何在集群外部动态创建参与者?
您可以建立单一执行元,而且它会在丛集中动态可用。如果执行单一执行元的丛集成员停止,丛集会在丛集中的某处衍生另一个单一执行元。
在集群中的每个节点上,或者在具有给定角色的每个节点上,使用ClusterSingleton扩展来生成单例。

// From the docs    
ClusterSingleton singleton = ClusterSingleton.get(system);
    // Start if needed and provide a proxy to a named singleton
    ActorRef<Counter.Command> proxy =
        singleton.init(SingletonActor.of(Counter.create(), "GlobalCounter"));

问题2:我们如何向参与者发送消息,以及参与者如何跨群集创建消息
使用代理引用将消息发送到单元集。

proxy.tell(Counter.Increment.INSTANCE);

从文件上看
当您需要在群集中的多个节点上分布执行元,并希望能够使用其逻辑标识符与它们进行交互,而不必关心它们在群集中的物理位置(该位置也可能会随时间变化)时,群集分片非常有用。
Q1:我们如何在集群外部动态创建参与者?
应该在每个实体类型的每个节点上调用群集分片init。可以使用角色来控制在哪些节点上创建实体参与者。init将根据节点的角色是否与实体的角色匹配来创建ShardRegion或代理。

EntityTypeKey<Counter.Command> typeKey = EntityTypeKey.create(Counter.Command.class, "Counter");

ActorRef<ShardingEnvelope<Counter.Command>> shardRegion =
    sharding.init(Entity.of(typeKey, ctx -> Counter.create(ctx.getEntityId())));

问题2:我们如何向参与者发送消息,以及参与者如何跨群集创建消息
然后通过EntityRef发送消息到特定实体。可以从EntityRef中检索entityId和实体键的名称。还可以将方法 Package 在ShardingEnvelope中或定义提取器函数并直接将消息发送到碎片区域。

EntityRef<Counter.Command> counterOne = sharding.entityRefFor(typeKey, "counter-1");
counterOne.tell(Counter.Increment.INSTANCE);

shardRegion.tell(new ShardingEnvelope<>("counter-1", Counter.Increment.INSTANCE));

您可以在执行元系统配置中定义碎片数。请注意,此值对于集群中的所有执行元系统都应相同,更改此值将需要在集群范围内重新启动。

akka.cluster.sharding {
  # Number of shards used by the default HashCodeMessageExtractor
  # when no other message extractor is defined. This value must be
  # the same for all nodes in the cluster and that is verified by
  # configuration check when joining. Changing the value requires
  # stopping all nodes in the cluster.
  number-of-shards = 1000
}

问题2:我们如何向参与者发送消息,以及参与者如何跨群集创建消息
或者,您可以使用Cluster Client从集群外部向集群中的参与者发送消息。
我强烈建议您阅读文档,因为这些是Akka集群中的一些深层主题。

相关问题