Akka集群:如何在路由消息之前等待n个路由器向路由器注册
我有一个需要3个节点的Akka群集:Akka集群:如何在路由消息之前等待n个路由器向路由器注册,akka,akka-cluster,Akka,Akka Cluster,我有一个需要3个节点的Akka群集: cluster { seed-nodes = [ "akka.tcp://ClusterSystem@127.0.0.1:2551" ,"akka.tcp://ClusterSystem@127.0.0.1:2552"] min-nr-of-members = 3 } 然后我使用集群单例启动一个actor,启动一个集群感知路由器: deployment { /parent/singleton/rou
cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@127.0.0.1:2551"
,"akka.tcp://ClusterSystem@127.0.0.1:2552"]
min-nr-of-members = 3
}
然后我使用集群单例启动一个actor,启动一个集群感知路由器:
deployment {
/parent/singleton/router1 {
router = round-robin-pool
nr-of-instances = 3
cluster {
enabled = on
max-nr-of-instances-per-node = 1
allow-local-routees = on
}
}
以下是初始化单例的方式:
@Override
public void preStart()
{
ActorRef router =
getContext().actorOf(
WorkerActor.props().withRouter(FromConfig.getInstance()),
"router1");
Runnable r = () -> {
for (int i = 0; i < 20; i++) {
WorkerActor.Message message = WorkerActor.Message.addAccount(
WorkerActor.Account.of("username_" + i,
"password_" + i)
);
router.tell(message, ActorRef.noSender());
}
};
getContext().getSystem().scheduler()
.scheduleOnce(Duration.ZERO, r,
getContext().dispatcher());
}
但这就像交叉手指,在开始发送消息之前,这3个实例已经准备好了
<> P> <强> >问题是什么是等待所有<代码> NR的实例在开始向它们发送消息之前需要准备好RouTee实例?< /强> < p>您可能需要考虑使用<代码> RealStEnMeNuppu回调。以下是一份相关报告的要点: 通过配置选项,您可以定义所需的成员数 在领导将“加入”成员的成员状态更改为“向上”之前: 您可以在
registerMemberUp
回调中启动参与者,该回调
将在当前成员状态更改为“Up”时调用,
i、 e.集群至少有定义数量的成员
您可能想考虑使用<代码> RealStEnMeNuppu回调。以下是一份相关报告的要点:
通过配置选项,您可以定义所需的成员数 在领导将“加入”成员的成员状态更改为“向上”之前: 您可以在registerMemberUp
回调中启动参与者,该回调
将在当前成员状态更改为“Up”时调用,
i、 e.集群至少有定义数量的成员
好的,在深入研究集群之前,我可能应该更仔细地阅读基本文档 这个问题的答案是向路由器发送
GetRoutees
消息,然后处理响应以检查已经添加了多少路由
此处记录了GetRoutees
:
将akka.routing.GetRoutees发送给路由器参与者将使其在akka.routing.routees消息中发回其当前使用的路由
实现可以如下所示:
@Override
public void preStart()
{
ActorRef router =
getContext()
.actorOf(Props.empty().withRouter(FromConfig.getInstance()),
"router1");
router.tell(GetRoutees.getInstance(), self());
}
@Override
public Receive createReceive()
{
return
ReceiveBuilder.create()
.match(Routees.class, r -> {
int noOfRoutees = r.getRoutees().size();
log().info("No of routees: {}", noOfRoutees);
if (noOfRoutees < 3)
getSender().tell(GetRoutees.getInstance(),
getSelf());
else
distributeMessages(getSender());
})
.matchAny(o -> log().info(
"oops, I don't understand this message {}",
o.getClass()))
.build();
}
@覆盖
公共无效预启动()
{
ActorRef路由器=
getContext()
.actorOf(Props.empty().withRouter(FromConfig.getInstance()),
“路由器1”);
tell(GetRoutees.getInstance(),self());
}
@凌驾
公共接收createReceive()
{
返回
ReceiveBuilder.create()
.match(Routees.class,r->{
int noOfRoutees=r.getRoutees().size();
log().info(“路由数目:{}”,无路由);
如果(不超过3)
getSender().tell(GetRoutees.getInstance(),
getSelf());
其他的
分发消息(getSender());
})
.matchAny(o->log().info(
“哎呀,我不明白这条消息{}”,
o、 getClass())
.build();
}
好的,在深入研究集群之前,我可能应该更仔细地阅读基本文档
这个问题的答案是向路由器发送GetRoutees
消息,然后处理响应以检查已经添加了多少路由
此处记录了GetRoutees
:
将akka.routing.GetRoutees发送给路由器参与者将使其在akka.routing.routees消息中发回其当前使用的路由
实现可以如下所示:
@Override
public void preStart()
{
ActorRef router =
getContext()
.actorOf(Props.empty().withRouter(FromConfig.getInstance()),
"router1");
router.tell(GetRoutees.getInstance(), self());
}
@Override
public Receive createReceive()
{
return
ReceiveBuilder.create()
.match(Routees.class, r -> {
int noOfRoutees = r.getRoutees().size();
log().info("No of routees: {}", noOfRoutees);
if (noOfRoutees < 3)
getSender().tell(GetRoutees.getInstance(),
getSelf());
else
distributeMessages(getSender());
})
.matchAny(o -> log().info(
"oops, I don't understand this message {}",
o.getClass()))
.build();
}
@覆盖
公共无效预启动()
{
ActorRef路由器=
getContext()
.actorOf(Props.empty().withRouter(FromConfig.getInstance()),
“路由器1”);
tell(GetRoutees.getInstance(),self());
}
@凌驾
公共接收createReceive()
{
返回
ReceiveBuilder.create()
.match(Routees.class,r->{
int noOfRoutees=r.getRoutees().size();
log().info(“路由数目:{}”,无路由);
如果(不超过3)
getSender().tell(GetRoutees.getInstance(),
getSelf());
其他的
分发消息(getSender());
})
.matchAny(o->log().info(
“哎呀,我不明白这条消息{}”,
o、 getClass())
.build();
}
我就是这么做的。我在onMemberUp
中开始的是一个集群单例参与者,它在preStart()方法中启动路由器(方法主体在我最初的问题中)。在相同的preStart()
方法中,我开始向路由器发送消息。似乎基础路由没有及时启动。这就是为什么我在发送消息之前增加一些延迟会起作用,但我发现这种方法很脆弱。我已经扫描了文档,似乎正确的方法是“手动”启动routees,然后在其周围创建router。我会试试的。好吧,我得说我在这里不知所措。我尝试了组路由器路径。我在启动时立即在集群成员中创建worker,然后使用registerMemberUp
hook启动集群singleton,启动路由器,开始向路由对象发送消息。如果我没有在创建路由器和发送消息之间添加延迟,那么所有消息都将发送到与路由器在同一节点上运行的一个路由器,如果我添加延迟,那么消息将被发送到所有节点上的所有工作进程。因此我不认为启动工作进程是问题,问题是路由器查找路由需要一些时间。一我
Cluster.get(system).registerOnMemberUp(new Runnable() {
@Override
public void run() {
// e.g. Send messages to cluster members
}
});
@Override
public void preStart()
{
ActorRef router =
getContext()
.actorOf(Props.empty().withRouter(FromConfig.getInstance()),
"router1");
router.tell(GetRoutees.getInstance(), self());
}
@Override
public Receive createReceive()
{
return
ReceiveBuilder.create()
.match(Routees.class, r -> {
int noOfRoutees = r.getRoutees().size();
log().info("No of routees: {}", noOfRoutees);
if (noOfRoutees < 3)
getSender().tell(GetRoutees.getInstance(),
getSelf());
else
distributeMessages(getSender());
})
.matchAny(o -> log().info(
"oops, I don't understand this message {}",
o.getClass()))
.build();
}