2017-12-27 349 views

回答

0

所有以sharded actor(實體)爲目標的消息都必須經過負責實體的givent類型的shard區域。一個碎片區域可以初始化這樣的:

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 
); 

爲了正確地將消息路由到實體,碎片區域必須能夠提取碎片-ID和實體的實體ID和碎片,它屬於。這是一個messageExtractor對象的作業(它必須實現IMessageExtractor接口)。

這裏的常見模式是創建一個專用信封,用於將實際消息路由到實體。在下面你可以看到一個例子 - shard id沒有被明確地提供,而是從實體id的模數最大的shards數量中計算出來的(這個值一旦被選中就不能改變)。

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> 

這意味着,如果要提取實體ID和當前演員的碎片-ID,您可以直接從演員的路徑做到這一點:

var entityId = Self.Path.Name; 
var shardId = Self.Path.Parent.Name; 
相關問題