.NET 7 SignalR(Kestrel)跨机器仅能建立10个WebSocket连接求助
SignalR跨机器仅能建立10个WebSocket连接的问题排查与解决
核心问题
基于.NET 7的SignalR应用,使用Kestrel作为服务器(已配置最大并发连接数50000),本地测试可建立约6000个连接,但跨机器网络环境下仅能成功建立10个连接。
可能原因及解决方案
1. 网络中间设备的连接数限制
这是最常见的原因:企业防火墙、路由器或负载均衡器通常会默认限制单客户端IP到目标服务器IP的并发连接数,默认阈值多为10-20个。本地测试无需经过这类设备,因此不受限制,但跨机器时会被拦截。
- 解决:
- 检查服务器与客户端之间的防火墙、路由器配置,调整单IP到目标服务的并发连接数限制,确保允许足够的连接量。
- 若无法修改网络设备配置,可尝试从多个客户端IP发起连接,验证是否是单IP限制导致。
2. 客户端操作系统的并发连接限制
操作系统对单进程发起的TCP并发连接或单目标IP的连接数存在默认限制:
- Windows系统:
MaxUserPort(可用端口范围)、TcpNumConnections等注册表参数可能制约连接数。 - Linux系统:
net.ipv4.ip_local_port_range(本地端口范围)、net.core.somaxconn(监听队列大小)等参数默认值可能不足。 - 解决:
- 调整客户端系统的TCP参数,扩大可用端口范围及并发连接限制。
- 将测试程序改为多进程/多线程模式,分散连接发起请求,规避单进程的系统限制。
3. Kestrel的隐藏配置或日志缺失
尽管已配置MaxConcurrentConnections和MaxConcurrentUpgradedConnections,但仍有其他Kestrel配置可能影响连接:
- 检查是否启用了请求限制中间件(如
UseRequestLimit),这类中间件可能限制并发请求数。 - 查看Serilog输出的详细日志,确认是否有连接建立失败的错误信息(如握手超时、连接被重置)。
4. 测试程序的实现缺陷
单线程循环发起连接可能存在以下问题:
StartConnection方法可能未正确处理WebSocket握手或SignalR连接初始化,导致部分连接静默失败。- 异步操作未正确并行化,连接建立速度过慢,触发服务器或客户端的超时机制。
Connections集合非线程安全,异步添加时可能出现异常(但通常不会仅限制到10个)。- 解决:
- 完善
StartConnection的异常捕获,输出InnerException获取详细错误原因。 - 改用并行方式发起连接(如
Parallel.ForEach或批量异步任务),但需控制并发度避免客户端过载。 - 验证
Connections集合的线程安全性,可使用ConcurrentBag<T>替代普通集合。
- 完善
5. 服务器端操作系统的TCP参数限制
服务器端操作系统的默认TCP参数可能无法支撑高并发连接:
- Windows:调整
TcpMaxConnectionsPerPath、MaxUserPort等注册表项。 - Linux:调整
net.core.somaxconn、net.ipv4.tcp_max_syn_backlog、net.ipv4.tcp_tw_reuse等内核参数。 - 解决:根据服务器操作系统,优化TCP参数以支持大量并发WebSocket连接。
排查步骤
- 抓包验证:在服务器端使用Wireshark抓包,确认第11个连接的请求是否到达服务器,排查是网络拦截还是服务器拒绝。
- 日志分析:查看Kestrel的Serilog日志及客户端测试程序的详细异常信息,定位连接失败的具体原因(超时、拒绝、重置等)。
- 工具替换:使用专业的SignalR负载测试工具发起跨机器连接,验证是否为测试程序自身问题。
内容的提问来源于stack exchange,提问作者AskAQucetion
相关产品推荐
相关产品推荐

