Akka.net 在隔离的节点上重启 actorsystem 终止
Akka.net restart actor system termination on node quarentined
我们正在开发一个带有 Akka.net v1.4.38 的集群,我们有使用 Akka.IO.TCP 与外部系统通信的种子节点,以及接收和发送消息到种子节点的多个客户端节点。如果客户端节点与集群失去通信,我们需要在该节点上重启 Akka actor 系统,因为它已被隔离。我们创建了一个侦听 AssociationErrorEvent 和 ThisActorSystemQuarantinedEvent 的 Actor,并在收到此消息时重新启动系统。
public class ErrorManagerActor: ReceiveActor {
public ErrorManagerActor(Action action) {
Receive<ThisActorSystemQuarantinedEvent>(m => {
action();
});
Receive<AssociationErrorEvent>(m => {
action();
});
}
}
问题是 actor 系统永远不会停止并在控制台中显示警告:
[CoordinatedShutdown (akka://xxxxx)] Coordinated shutdown phase
[actor-system-terminate] timed out after 00:00:10
我们创建了一个单元测试来重现该问题。
[Test]
public void TerminateSystemTest() {
var actor = Sys.ActorOf(Props.Create<ErrorManagerActor>(() => {
if (!Sys.Terminate().Wait(10000))
Assert.Fail("Unable to terminate actor system");
terminatedEvent.Set();
}));
Sys.EventStream.Subscribe(actor, typeof(AssociationErrorEvent));
Sys.EventStream.Subscribe(actor, typeof(ThisActorSystemQuarantinedEvent));
var cluster = Cluster.Get(Sys);
Sys.EventStream.Publish(new ThisActorSystemQuarantinedEvent(cluster.SelfAddress, cluster.SelfAddress));
terminatedEvent.WaitOne();
}
你的测试失败的原因是为了让 ActorSystem
终止它必须先杀死所有演员,包括 运行你的测试断言。因此让 actor 在 System.Terminate
上执行阻塞 Task.Wait
将导致死锁。
要在生产系统中修复此问题,不要等待 Task
。
我们正在开发一个带有 Akka.net v1.4.38 的集群,我们有使用 Akka.IO.TCP 与外部系统通信的种子节点,以及接收和发送消息到种子节点的多个客户端节点。如果客户端节点与集群失去通信,我们需要在该节点上重启 Akka actor 系统,因为它已被隔离。我们创建了一个侦听 AssociationErrorEvent 和 ThisActorSystemQuarantinedEvent 的 Actor,并在收到此消息时重新启动系统。
public class ErrorManagerActor: ReceiveActor {
public ErrorManagerActor(Action action) {
Receive<ThisActorSystemQuarantinedEvent>(m => {
action();
});
Receive<AssociationErrorEvent>(m => {
action();
});
}
}
问题是 actor 系统永远不会停止并在控制台中显示警告:
[CoordinatedShutdown (akka://xxxxx)] Coordinated shutdown phase [actor-system-terminate] timed out after 00:00:10
我们创建了一个单元测试来重现该问题。
[Test]
public void TerminateSystemTest() {
var actor = Sys.ActorOf(Props.Create<ErrorManagerActor>(() => {
if (!Sys.Terminate().Wait(10000))
Assert.Fail("Unable to terminate actor system");
terminatedEvent.Set();
}));
Sys.EventStream.Subscribe(actor, typeof(AssociationErrorEvent));
Sys.EventStream.Subscribe(actor, typeof(ThisActorSystemQuarantinedEvent));
var cluster = Cluster.Get(Sys);
Sys.EventStream.Publish(new ThisActorSystemQuarantinedEvent(cluster.SelfAddress, cluster.SelfAddress));
terminatedEvent.WaitOne();
}
你的测试失败的原因是为了让 ActorSystem
终止它必须先杀死所有演员,包括 运行你的测试断言。因此让 actor 在 System.Terminate
上执行阻塞 Task.Wait
将导致死锁。
要在生产系统中修复此问题,不要等待 Task
。