Иногда узел не присоединяется к кластеру 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, если хотите попробовать новые биты прямо сейчас.

Другие вопросы по тегам