是否可以将 100000 个 SignalR 用户连接到单个 IIS?
Is it possible to connect 100000 SignalR users to single IIS?
我想将 100000 个 SignalR 用户连接到 IIS (Windows Server 2016)。一切正常,直到大约 16000 个连接。然后我开始收到这个错误:
Only one usage of each socket address (protocol/network address/port) is normally permitted
这是我的客户端代码 - 这是一个创建所有 SignalR 对象并连接到服务器的循环:
private static void Run()
{
for (int i = 0; i < 100000 ; i++)
{
Guid g = Guid.Empty;
string lG = g.ToString();
string lGS = lG.Substring(0, lG.Length - i.ToString().Length);
string lTenantIdentfier = lGS + i.ToString();
bool lConnected = false;
SignalRClient sc = new SignalRClient(lTenantIdentfier);
while (!lConnected)
{
sc.Stop();
lConnected = sc.Connect();
if (lConnected)
break;
Console.WriteLine("[" + lTenantIdentfier + "] - Repeating connection...");
System.Threading.Thread.Sleep(5000);
}
if ((i % 1000) == 0)
Thread.Sleep(5000);
}
Console.ReadKey();
}
连接函数:
public bool Connect()
{
try
{
if (connection != null)
{
Stop();
}
if (connection == null)
{
connection = new HubConnection("my_url");
connection.Headers.Add("TenantIdentifier", TenantIdentifier);
HubProxy = connection.CreateHubProxy("notificationHub");
GetNotification = HubProxy.On("NotifyChange", () =>
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("[" + TenantIdentifier + "] " + DateTime.Now);
});
}
connection.Start().Wait();
if (connection.State == ConnectionState.Connected)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("[" + TenantIdentifier + "] - Connected");
connection.Closed -= Connection_Closed;
connection.Closed += Connection_Closed;
return true;
}
}
catch (Exception ex)
{
//Show exception
}
return false;
}
我在 下添加到 machine.config:
<processModel autoConfig="false" maxIoThreads="999999" maxWorkerThreads="999999" memoryLimit="999999" minIoThreads="999999" minWorkerThreads="999999" />
我添加到注册表:
最大用户端口 65535
TcpTimedWaitDelay 30
我想 IIS 没有更多的空闲套接字或端口。也许我错了 - 我能以某种方式调整它吗?
正如评论中所讨论的那样,原因似乎是 客户端 运行 没有空闲端口。 MaxUserPort
在 windows 上的默认值为 5000,因此只有从 1024 到 4999 的端口可供客户端连接到服务器。服务器本身不能通过这种方式 运行 占用空闲端口,因为所有连接都转到同一个端口(以通常的网络服务器为例,所有客户端都连接到端口 80 或端口 443 等,此处相同)。
然后您尝试从客户端循环连接,每次连接都使用新的本地端口。我怀疑您可以连接超过 (4999-1024) 次,因为您没有明确关闭 signalR 连接,但您也没有将它们存储在某种全局列表中,因此它们有资格进行垃圾收集,这会调用终结器,这反过来又关闭了连接。或者连接通过其他方式关闭,但速度不够快,所以有时您会耗尽客户端上的本地端口,但您拥有的数量可能并不代表 并发 连接数。
在 client 上将 MaxUserPort 设置为 65535 并将 TcpTimedWaitDelay 设置为 30 应该允许您从该客户端建立更多连接。
Evk 是正确的,但我记得在查看用户连接量时读过一些有趣的东西。
来自最初的 SignalR 领导者 Damien Edwards,早在 2014 年...是的,这是可能的。这将在 ASP.NET 版本 2.x 下。但是,如果您阅读了一些回复,Damien 表示 .NET CORE 版本应该更高。
https://twitter.com/DamianEdwards/status/486642486350061568
10GB svr 上的新@SignalR 并发连接记录:150,000 个连接(WebSockets),带有实验性缓冲区池更改。
我想将 100000 个 SignalR 用户连接到 IIS (Windows Server 2016)。一切正常,直到大约 16000 个连接。然后我开始收到这个错误:
Only one usage of each socket address (protocol/network address/port) is normally permitted
这是我的客户端代码 - 这是一个创建所有 SignalR 对象并连接到服务器的循环:
private static void Run()
{
for (int i = 0; i < 100000 ; i++)
{
Guid g = Guid.Empty;
string lG = g.ToString();
string lGS = lG.Substring(0, lG.Length - i.ToString().Length);
string lTenantIdentfier = lGS + i.ToString();
bool lConnected = false;
SignalRClient sc = new SignalRClient(lTenantIdentfier);
while (!lConnected)
{
sc.Stop();
lConnected = sc.Connect();
if (lConnected)
break;
Console.WriteLine("[" + lTenantIdentfier + "] - Repeating connection...");
System.Threading.Thread.Sleep(5000);
}
if ((i % 1000) == 0)
Thread.Sleep(5000);
}
Console.ReadKey();
}
连接函数:
public bool Connect()
{
try
{
if (connection != null)
{
Stop();
}
if (connection == null)
{
connection = new HubConnection("my_url");
connection.Headers.Add("TenantIdentifier", TenantIdentifier);
HubProxy = connection.CreateHubProxy("notificationHub");
GetNotification = HubProxy.On("NotifyChange", () =>
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("[" + TenantIdentifier + "] " + DateTime.Now);
});
}
connection.Start().Wait();
if (connection.State == ConnectionState.Connected)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("[" + TenantIdentifier + "] - Connected");
connection.Closed -= Connection_Closed;
connection.Closed += Connection_Closed;
return true;
}
}
catch (Exception ex)
{
//Show exception
}
return false;
}
我在
<processModel autoConfig="false" maxIoThreads="999999" maxWorkerThreads="999999" memoryLimit="999999" minIoThreads="999999" minWorkerThreads="999999" />
我添加到注册表:
最大用户端口 65535 TcpTimedWaitDelay 30
我想 IIS 没有更多的空闲套接字或端口。也许我错了 - 我能以某种方式调整它吗?
正如评论中所讨论的那样,原因似乎是 客户端 运行 没有空闲端口。 MaxUserPort
在 windows 上的默认值为 5000,因此只有从 1024 到 4999 的端口可供客户端连接到服务器。服务器本身不能通过这种方式 运行 占用空闲端口,因为所有连接都转到同一个端口(以通常的网络服务器为例,所有客户端都连接到端口 80 或端口 443 等,此处相同)。
然后您尝试从客户端循环连接,每次连接都使用新的本地端口。我怀疑您可以连接超过 (4999-1024) 次,因为您没有明确关闭 signalR 连接,但您也没有将它们存储在某种全局列表中,因此它们有资格进行垃圾收集,这会调用终结器,这反过来又关闭了连接。或者连接通过其他方式关闭,但速度不够快,所以有时您会耗尽客户端上的本地端口,但您拥有的数量可能并不代表 并发 连接数。
在 client 上将 MaxUserPort 设置为 65535 并将 TcpTimedWaitDelay 设置为 30 应该允许您从该客户端建立更多连接。
Evk 是正确的,但我记得在查看用户连接量时读过一些有趣的东西。
来自最初的 SignalR 领导者 Damien Edwards,早在 2014 年...是的,这是可能的。这将在 ASP.NET 版本 2.x 下。但是,如果您阅读了一些回复,Damien 表示 .NET CORE 版本应该更高。
https://twitter.com/DamianEdwards/status/486642486350061568
10GB svr 上的新@SignalR 并发连接记录:150,000 个连接(WebSockets),带有实验性缓冲区池更改。