Иногда узел не присоединяется к кластеру Akka.Net после перезапуска IIS AppPool
Мы создали инфраструктуру кластера Akka для SMS-сообщений, электронной почты и push-уведомлений. В системе существует 3 вида узлов: клиент, отправитель и маяк. Роль клиента используется веб-приложением и приложением API (веб-интерфейс и API размещаются в IIS). Роли Lighthouse и Sender размещаются в качестве службы Windows. Принимая во внимание, что веб-приложение и приложение API AppPools перезапускаются из-за IIS, в событии Start и Stop global.asax.cs мы выключаем систему акторов в ролях клиента и запускаем заново. Мы можем наблюдать через журналы, что система успешно завершает работу и присоединяется к Кластеру.
Но иногда, когда AppPool перезагружается, клиент ActorSystem запускается, но не может присоединиться к кластеру, и наше уведомление перестает работать (что является для нас огромной проблемой). Когда мы вручную удаляем ActorSystem и снова запускаем его вручную, он присоединяется к кластеру. Такая ситуация происходит примерно каждые два дня.
Мы видим, что Клиент присоединяется к Кластеру до появления Ошибки;
Узел [akka.tcp: // NotificationSystem @.,,:41350] ПРИСОЕДИНЯЕТСЯ, Роли [клиент]
Лидер - это движущийся узел [akka.tcp: // NotificationSystem @.,,:41350] до [Вверх]
Просматривая журналы, мы видим следующую ошибку после того, как клиент присоединяется к кластеру;
Адрес выключения: akka.tcp: // NotificationSystem @.,,:41350Akka.Remote.ShutDownAssociation: Адрес выключения: akka.tcp: // NotificationSystem @.,,:41350 ---> Akka.Remote.Transport.InvalidAssociationException: удаленная система прервала связь, потому что она закрывается. --- Конец внутренней трассировки стека исключений --- в Akka.Remote.EndpointWriter.PublishAndThrow(Причина исключения, уровень LogLevel) в Akka.Remote.EndpointWriter.b__20_0(Исключение ex) в Akka.Actor.LocalOnlyDecider.Decide(Причина исключения) в Akka.Actor.OneForOneStrategy.Handle(дочерний элемент IActorRef, исключительная ситуация x) в Akka.Actor.SupervisorStrategy.HandleFailure(actorCell actorCell, причина исключения, ChildRestartStats failedChildStats, IReadOnlyCollection1 allChildA). Akka.Actor.ActorCell.SystemInvoke(Envelope envelope)--- Конец трассировки стека из предыдущего местоположения, где было сгенерировано исключение --- в Akka.Actor.ActorCell.HandleFailed(Failed f) в Akka.Actor.ActorCell.SystemInvoke (Envelope конверт)Akka.Remote.ShutDownAssociation: Адрес выключения: akka.tcp: // NotificationSystem @.,,:41350 ---> Akka.Remote.Transport.InvalidAssociationException: удаленная система прервала связь, потому что она закрывается. --- Конец внутренней трассировки стека исключений --- в Akka.Remote.EndpointWriter.PublishAndThrow(Причина исключения, уровень LogLevel) в Akka.Remote.EndpointWriter.b__20_0(Исключение ex) в Akka.Actor.LocalOnlyDecider.Decide(Причина исключения) в Akka.Actor.OneForOneStrategy.Handle(дочерний элемент IActorRef, исключительная ситуация x) в Akka.Actor.SupervisorStrategy.HandleFailure(actorCell actorCell, причина исключения, ChildRestartStats failedChildStats, IReadOnlyCollection`1AiledAllAfeAllAiledAllAfeCoundAllChildAlCa)) в Akka.Actor.ActorCell.SystemInvoke (Конверт конверта) --- Конец трассировки стека от предыдущего местоположения, где было сгенерировано исключение --- в Akka.Actor.ActorCell.HandleFailed (Ошибка f) в Akka.Actor.ActorCell.SystemInvoke (Конверт-конверт)
После ошибки мы видим следующее сообщение об ошибке;
Ассоциация с [akka.tcp: // NotificationSystem @.,,:41350], имеющий UID [226948907], неисправим. Теперь UID помещен на карантин, и все сообщения с этим UID будут доставляться в виде пустых писем. Удаленная система актеров должна быть перезапущена для выхода из этой ситуации.
Без перезапуска действующего субъекта система не исправляет себя.
Наша конфигурация роли клиента:
<akka>
<hocon>
<![CDATA[
akka{
loglevel = DEBUG
actor{
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
deployment {
/coordinatorRouter {
router = round-robin-group
routees.paths = ["/user/NotificationCoordinator"]
cluster {
enabled = on
max-nr-of-instances-per-node = 1
allow-local-routees = off
use-role = sender
}
}
}
serializers {
wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
}
serialization-bindings {
"System.Object" = wire
}
debug{
receive = on
autoreceive = on
lifecycle = on
event-stream = on
unhandled = on
}
}
remote {
helios.tcp {
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
applied-adapters = []
transport-protocol = tcp
hostname = "***.***.**.**"
port = 0
}
}
cluster {
seed-nodes = ["akka.tcp://NotificationSystem@***.***.**.**:5053", "akka.tcp://NotificationSystem@***.***.**.**:5073"]
roles = [client]
}
}
]]>
</hocon>
Наша конфигурация роли отправителя:
<akka>
<hocon><![CDATA[
akka{
loglevel = INFO
loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"]
actor{
debug {
# receive = on
# autoreceive = on
# lifecycle = on
# event-stream = on
# unhandled = on
}
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
serializers {
wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
}
serialization-bindings {
"System.Object" = wire
}
deployment{
/NotificationCoordinator/ApplePushNotificationActor{
router = round-robin-pool
resizer{
enabled = on
lower-bound = 3
upper-bound = 5
}
}
/NotificationCoordinator/AndroidPushNotificationActor{
router = round-robin-pool
resizer{
enabled = on
lower-bound = 3
upper-bound = 5
}
}
/NotificationCoordinator/EmailActor{
router = round-robin-pool
resizer{
enabled = on
lower-bound = 3
upper-bound = 5
}
}
/NotificationCoordinator/SmsActor{
router = round-robin-pool
resizer{
enabled = on
lower-bound = 3
upper-bound = 5
}
}
/NotificationCoordinator/LoggingCoordinator/ResponseLoggerActor{
router = round-robin-pool
resizer{
enabled = on
lower-bound = 3
upper-bound = 5
}
}
}
}
remote{
log-remote-lifecycle-events = DEBUG
log-received-messages = on
helios.tcp{
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
applied-adapters = []
transport-protocol = tcp
#will be populated with a dynamic host-name at runtime if left uncommented
#public-hostname = "POPULATE STATIC IP HERE"
hostname = "***.***.**.**"
port = 0
}
}
cluster {
seed-nodes = ["akka.tcp://NotificationSystem@***.***.**.**:5053", "akka.tcp://NotificationSystem@***.***.**.**:5073"]
roles = [sender]
}
}
]]></hocon>
Как мы можем решить эту проблему? Спасибо.
1 ответ
Это определенно ошибка в EndpointManager в Akka.Remote. Akka.NET 1.1, которая должна быть выпущена 14 июня, должна решить эту проблему. Мы исправили кучу ошибок повторного объединения кластеров, но они еще не были выпущены. Akka.Cluster будет RTM-ed как часть этого выпуска.
Тем временем вы также можете попробовать использовать Akka.NET Nightly Builds, если хотите попробовать новые биты прямо сейчас.