SignalR在IIS上阻塞:超10个客户端访问时页面加载异常
问题分析与解决方案
你的问题核心是引入SignalR后系统并发用户数骤降,结合IIS配置、SignalR连接管理及业务逻辑,给出以下针对性解决步骤:
1. 检查并调整IIS应用程序池配置
- 打开IIS管理器,找到对应应用程序池:
- 调整最大工作进程数:默认是1,可根据服务器CPU核心数设置(比如2-4),提升并发处理能力。
- 检查队列长度:默认是1000,若服务器资源允许可适当增大,避免请求排队阻塞。
- 关闭快速失败保护:在“高级设置”中找到该选项,暂时禁用,排除因进程意外退出导致的连接限制。
- 检查WebSocket配置:确认IIS的WebSocket模块已启用,且站点“WebSocket”功能设置中的“最大并发WebSocket连接数”未被限制为10。
2. 修复SignalR连接资源泄漏问题
后端Hub添加断开连接清理逻辑
你的NotificationHub未实现连接断开时的资源回收,静态字典signalConnectionList会持续累积无效连接,导致内存占用过高甚至线程锁竞争。添加以下代码:
public class NotificationHub : Hub { // ... 原有代码 public override async Task OnDisconnectedAsync(Exception exception) { // 从静态字典中移除当前无效连接 if (ConstantDictionaryVM.signalConnectionList.TryRemove(Context.ConnectionId, out _)) { // 可添加日志记录连接断开事件 } await base.OnDisconnectedAsync(exception); } }
同时将signalConnectionList改为线程安全的ConcurrentDictionary,避免多线程操作阻塞:
// 修改ConstantDictionaryVM中的定义 public static ConcurrentDictionary<string, int> signalConnectionList = new ConcurrentDictionary<string, int>();
前端优化连接释放逻辑
当前前端调用$.connection.hub.stop()后未清理广播通道资源,可能导致内存泄漏。修改代码:
const bc = new BroadcastChannel("my-awesome-site"); bc.onmessage = (event) => { if (event.data === `Other Disconnect Please`) { console.log(`Another tab of this site just got opened`); $.connection.hub.stop().done(function () { console.log("closed signalr"); // 关闭广播通道,释放资源 bc.close(); // 解绑SignalR相关事件 $.connection.hub.off(); }); } }; bc.postMessage(`Other Disconnect Please`);
3. 调整SignalR核心配置参数
在Startup.cs中添加超时与心跳配置,快速回收无效连接:
public void Configuration(IAppBuilder app) { var hubConfiguration = new HubConfiguration(); hubConfiguration.EnableDetailedErrors = true; // 调整连接超时与心跳间隔,及时回收僵死连接 GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(30); GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10); // 禁用JavaScript代理(如果已手动生成hub.js) hubConfiguration.EnableJavaScriptProxies = false; app.MapSignalR(hubConfiguration); }
4. 排查服务器系统资源与网络限制
- 任务管理器监控CPU、内存:当用户数达到10时,若资源使用率接近100%,需升级服务器配置或优化业务逻辑的资源消耗。
- 检查TCP连接状态:打开命令提示符执行
netstat -ano | findstr TIME_WAIT,若存在大量TIME_WAIT状态连接,可调整Windows注册表参数:- 新增
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下的TcpTimedWaitDelay(DWORD值,设为30,单位秒) - 新增
MaxUserPort(DWORD值,设为65534),扩大可用端口范围
- 新增
5. 优化Session状态配置
若系统未依赖Session,可在web.config中禁用Session以减少并发阻塞:
<system.web> <sessionState mode="Off" /> </system.web>
若必须使用Session,将模式改为StateServer或SQLServer,避免InProc Session导致的进程内资源竞争。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

