シードとクライアントプロセスを持つakka.netクラスタを作成する2つのコマンドラインプロジェクトを持つソリューションがあります。シードはクラスタを開始し、次に、インターフェイス "IHasRouting"を実装するすべてのメッセージに対してハッシュマッピングを実行する整合性のあるハッシュクラスタルータをインスタンス化します。したがって、(シードまたはクライアントからの)IHasRoutingメッセージは、そのメッセージのハッシュのルート上のシードに終わるはずです。クラスタ化された一貫性のあるハッシュプールで同じマッピングの新しいルートを作成
プロジェクトは正常に開始され、クラスタはエラーなしで形成されます。シードとクライアントの両方がルータをインスタンス化します。シードとクライアントからのすべてのメッセージは同じ「VolumeId」を持つため、シードの同じルートに移動する必要があります。 BUTクライアントノードからのメッセージは、シードのメッセージの新しいルートになります。
- アンIActorRefが、それは、そのノード内の俳優がルータにメッセージを送信する各ノードで終了する必要がありますrepresting:一貫性のあるハッシュクラスタ・ルータの
私の理解では、ということです。
- ルータのインプレッションは、各ノードで同じで、同じアクター名を持つ必要があります。
- ルータへのすべてのメッセージは、IConsistentHashまたはルータインスタンスが同じハッシュを持つすべてのメッセージは一つだけrouteeに到着すると、それは常に同じroutee
- Aになります「WithHashMapping()」
- を持っている必要があります実装する必要がありますルートは複数のハッシュを取るかもしれない
私は一貫性のあるハッシュクラスタルータがどのように動作すべきか、そして多くのデバイスがルータタイプを正しく使用しているように見えると信じています。 。 助けてください!そうすれば、私は完全なソリューションを提供することができます。
ルータを作成するコード:
system.ActorOf(
new ClusterRouterPool(
local: new ConsistentHashingPool(nrOfInstances: 1)
.WithHashMapping(m => (m as IHasRouting)?.Company?.VolumeId ?? throw new Exception("no routing!")),
settings: new ClusterRouterPoolSettings(
100,
100,
allowLocalRoutees: allowLocalRoutees, //true if the node role is a Seed
useRole: "Seed"))
.Props(Props.Create(() => new CompanyDeliveryActor())), "company-router");
私はルータへのメッセージのために必要とされる、「当社」クラスを持っています。すべてのVolumeIdはこのテストで同じです。
public class Company
{
public readonly Guid CompanyId;
public readonly Guid VolumeId;
public readonly string CompanyName;
public Company(Guid companyId, Guid volumeId, string companyName)
{
this.CompanyId = companyId;
this.VolumeId = volumeId;
this.CompanyName = companyName;
}
}
ルータマッピングによって使用さIHasRoutingインタフェース:ルータに送信することができる
public interface IHasRouting
{
Company Company { get; }
}
例えばメッセージクラス:
public class GetTripsMessage : IHasRouting
{
public Company Company { get; private set; }
public GetTripsMessage(Company company)
{
this.Company = company;
}
}
そして最後にあるCompanyDeliverActorルータのルートごとにインスタンス化されます。
public class CompanyDeliveryActor : ReceiveActor
{
private readonly Dictionary<Guid, IActorRef> companyManagers = new Dictionary<Guid, IActorRef>();
private readonly Guid instanceid = Guid.NewGuid();
public CompanyDeliveryActor()
{
this.Receive<GetTripsMessage>(m => this.RouteCompanyMessage(m, m.Company));
this.Receive<SetTripsMessage>(m => this.RouteCompanyMessage(m, m.Company));
}
private void RouteCompanyMessage(object m, Company company)
{
//placing a watch here shows that this.instanceid is different for messages from the client.
if (!this.companyManagers.TryGetValue(company.CompanyId, out var manager))
{
manager = Context.ActorOf(Props.Create(() => new CompanyManagerActor()));
this.companyManagers[company.CompanyId] = manager;
}
manager.Tell(m, Context.Sender);
}
}
ありがとうございました。
ありがとうございます - 私の理解は間違っています。 IActorRefが1つしか存在していないことと、分散のためにクラスタ一貫性のあるhash-pool-routerにメッセージを送信したい他のすべてのアクター(おそらく他のノード上)に渡されるべきであることは分かりませんでした。 –
これはあなたに他のより高度なオプションがある理由です。なぜあなたの正確なユースケースがわからないのですが、間違って一貫してハッシュルータを選ぶことが多いのですが、実際に必要なのはクラスタシャーディングです(私が回答したブログ記事を読んでください)。 – Horusiath