我有一个解决方案,包含2个命令行项目,创建一个带有种子和客户端进程的akka.net集群。种子启动群集,然后实例化一个一致的散列簇路由器,该路由器对实现我的接口“IHasRouting”的任何消息执行散列映射。因此,任何IHasRouting消息(来自种子或客户端)应最终在该消息散列的路由器上种子。集群一致的散列池为相同的映射生成新的routee
项目正常启动并且群集表单没有错误。种子和客户端实例化路由器。来自种子和客户端的所有消息都具有相同的“VolumeId”,因此它们应该在种子中转到相同的路由。 但是来自客户端节点的消息为这些消息在种子上产生了新的routee!
我一致的散列集群路由器的理解是:
- 的IActorRef represting它应该退出,其中的演员在该节点打算将消息发送到路由器的每个节点上。
- 路由器的实现应该在每个节点上相同,并且具有相同的actor名称。
- 到路由器的所有信息应实现IConsistentHash或路由器的情况下应该有一个“WithHashMapping()”
- 具有相同散列所有消息都将只在一个routee到达,这将始终是相同的routee
- 一routee可能需要不止一个哈希
我相信我的理解一致的散列集群路由器应该如何表现和大量的开发者并似乎被正确使用路由器的类型,所以我的实现必须是错的.. 。 请帮忙!如果有帮助,我可以提供完整的解决方案。
创建路由器代码:
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");
我有一个消息需要的路由器一个“公司”类。所有VolumeIds对于此测试都是相同的。
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应该存在,并且它应该传递给所有其他节点(可能在其他节点上),以便将消息发送到集群一致性哈希池路由器进行分发。 –
这就是为什么你有其他更高级的选项。我不知道为什么你的确切用例,但我知道人们通常会错误地选择一致的哈希路由器,而他们实际上需要的是集群分片(请阅读我在答案中链接的博客文章)。 – Horusiath