Клиент кластера Akka.NET - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь создать приложение, используя Akka.NET.

Основная цель - создать сервер, который может обрабатывать множество клиентских подключений и запросов одновременно.Я выбрал Akka.NET для этого.У меня есть кластер, который сейчас состоит только из 1 узла.

У меня также есть клиенты кластера (ClusterClient), которые одновременно начинают подключаться к серверу.Логика клиента проста: он подключается к серверу и подписывается на него.Проблем с публикацией пока нет, клиенты получают все, если соединение стабильно.Где-то около ~ 4000-5000 клиентских подключений, начинается повторное подключение, и, соответственно, соединение теряется.Я попытался добавить второй узел в кластер и сделать 3000 подключений для каждого узла, но это было безуспешно.

Вопрос в том, как создать сервер на AKKA.Net, который будет содержать большое количествосоединения (например, 100 000 - 1 000 000).И можно ли использовать для этой цели кластер?

Сервер

using Akka.Actor;
using Akka.Configuration;
using System;
using System.Configuration;
using Akka.Cluster.Tools.Client;
using System.Threading;

namespace CoreSPServer
{
    class Program
    {
        static void Main(string[] args)
        {
            Config config = ConfigurationFactory.ParseString(ConfigurationManager.AppSettings["ClusterConfig"]);
            ActorSystem system = ActorSystem.Create("ClusterSystem", config);
            var publisher = system.ActorOf(Props.Create(() => new Publisher()), "Publisher");
            var clientSub = system.ActorOf(Props.Create(() => new ClientSubscriber()), "Sub");

            ClusterClientReceptionist.Get(system).RegisterService(clientSub);

            if (Console.ReadLine() == "start")
            {
                    publisher.Tell("test");
                    Thread.Sleep(10);
            }

            Console.ReadKey();
        }
    }
}

ClientSubscriber и издатель

class ClientSubscriber : ReceiveActor
{
    public ClientSubscriber()
    {
        var mediator = DistributedPubSub.Get(Context.System).Mediator;

        Receive<IActorRef>(senderToSub =>
        {
            mediator.Tell(new Subscribe("content", senderToSub));
        });
    }
}

public class Publisher : ReceiveActor
    {
        public Publisher()
        {
            var mediator = DistributedPubSub.Get(Context.System).Mediator;

            Receive<string>(str =>
            {
                var upperCase = str.ToUpper();
                mediator.Tell(new Publish("content", upperCase));
            });
        }
    }

Клиент

static void Main(string[] args)
        {
            var config = ConfigurationFactory.ParseString(ConfigurationManager.AppSettings["ClientConf"]);
            ActorSystem Sys = ActorSystem.Create("ClusterClient", config);

            //Connection path to Cluster Node
            var initialContacts = new List<ActorPath>(){
                    ActorPath.Parse("akka.tcp://ClusterSystem@localhost:5001/system/receptionist"),
            }.ToImmutableHashSet();
            var settings = ClusterClientSettings.Create(Sys).WithInitialContacts(initialContacts);

            for(int i = 0; i < 5000; i++)
            {
                    IActorRef c = Sys.ActorOf(ClusterClient.Props(settings), "client" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
                    var asd = Sys.ActorOf(Props.Create<Subscriber>(), "clientSub" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
                    c.Tell(new ClusterClient.Send("/user/Sub5001", asd));
                    Thread.Sleep(1/10);
            }

            Console.ReadKey();
        }

Конфигурация сервера

akka {
extensions = [&quot;Akka.Cluster.Tools.Client.ClusterClientReceptionistExtensionProvider, Akka.Cluster.Tools&quot;]
actor.provider = cluster
remote {
    dot-netty.tcp {
        port = 5001
        public-hostname = localhost
        auto-down-unreachable-after = off
    }
}
cluster {
   seed-nodes = [&quot;akka.tcp://ClusterSystem@localhost:5001&quot;]
}
}
...