如何在Akka.NET中将实体ID分配给分片的实体?

问题描述 投票:-1回答:1

我不明白在ShardRegion中创建一个新actor时如何分配ID,我正在查看这个示例

https://github.com/akkadotnet/akka.net/tree/dev/src/examples/Cluster/ClusterSharding/ClusterSharding.Node

如果有人有一个更清晰的例子,那将是伟大的。

c# visual-studio sharding akka.net
1个回答
0
投票

所有针对分片角色(实体)的消息都必须通过负责该实体的给定类型的分片区域。可以像这样初始化分片区域:

var sharding = ClusterSharding.Get(system);
var shardRegion = sharding.Start(
    typeName: nameof(MyActor), 
    entityProps: Props.Create<MyActor>(), // the Props used to create entities
    settings: ClusterShardingSettings.Create(system),
    messageExtractor: messageExtractor
);

为了正确地将消息路由到实体,分片区域必须能够提取该实体的shard-id和entity-id以及它所属的分片。这是一个messageExtractor对象的工作(它必须实现IMessageExtractor接口)。

这里的一个常见模式是创建一个专用信封,用于将实际消息路由到实体。下面你可以看到一个例子 - 没有显式提供shard id,而是根据实体id模数的散列计算最大分片数(这个值一旦被选中,就不能改变)。

public sealed class ShardEnvelope
{
    public readonly string EntityId;
    public readonly object Payload;

    public ShardEnvelope(string entityId, object payload)
    {
        EntityId = entityId;
        Payload = payload;
    }
}

public sealed class MessageExtractor : HashCodeMessageExtractor
{
    public MessageExtractor(int maxNumberOfShards) : base(maxNumberOfShards) { }
    public override string EntityId(object message) => 
        (message as ShardEnvelope)?.EntityId;
    public override object EntityMessage(object message) => 
        (message as ShardEnvelope)?.Payload;
}

现在,虽然实体生命周期完全由集群分片管理,并且它们在集群中的实际本地化可能会随着时间的推移而发生变化(由于重新平衡),但它们在给定集群节点内的相对路径始终保持不变,并且它符合以下模式:

/user/sharding/<typeName>/<shard-id>/<entity-id>

这意味着,如果要提取当前actor的entity-id和shard-id,可以直接从actor的路径执行:

var entityId = Self.Path.Name;
var shardId = Self.Path.Parent.Name;
© www.soinside.com 2019 - 2024. All rights reserved.