我尝试使用 Akka.NET 创建应用程序。
主要目标是制作一个可以同时处理许多客户端连接和请求的服务器。我为此选择了 Akka.NET。我有一个集群,现在只包含 1 个节点。
我还有同时开始连接到服务器的集群客户端 (ClusterClient)。客户端的逻辑很简单:它连接到服务器并在那里订阅一个actor。发布还没有问题,客户得到了一切,当然,如果连接稳定的话。大约 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();
}
}
}
客户订阅者和发布者
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 = ["Akka.Cluster.Tools.Client.ClusterClientReceptionistExtensionProvider, Akka.Cluster.Tools"]
actor.provider = cluster
remote {
dot-netty.tcp {
port = 5001
public-hostname = localhost
auto-down-unreachable-after = off
}
}
cluster {
seed-nodes = ["akka.tcp://ClusterSystem@localhost:5001"]
}
}