You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server应用20余用户同时访问时故障求助

Blazor Server 多用户访问故障排查与解决建议

核心问题分析

日志中的Microsoft.JSInterop.JSDisconnectedException表明,Blazor电路已断开并销毁后,RadzenContextMenu组件仍尝试发起JavaScript互操作调用。结合20+用户触发故障的场景,大概率是服务器资源瓶颈导致电路意外终止,或是组件生命周期未正确处理电路断开状态。


一、服务器资源瓶颈排查

  • 内存监控

    • 实时跟踪w3wp.exe的内存占用,确认是否存在内存泄漏(内存持续攀升至接近8GB上限)
    • 检查应用中未释放的资源:如未取消的异步任务、未Dispose的IDisposable对象、长期订阅的事件
  • CPU负载检查

    • 查看w3wp.exe的CPU使用率,若持续超过80%,会导致服务器无法及时处理SignalR心跳包,触发电路超时断开

二、Blazor与SignalR配置优化

1. 细化电路与Hub配置

在Program.cs中补充以下配置,优化资源管理与连接稳定性:

builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
        options.KeepAliveInterval = TimeSpan.FromSeconds(15);
        // 增大最大接收消息大小,避免大消息导致连接中断
        options.MaximumReceiveMessageSize = 10 * 1024 * 1024; // 10MB
        options.StreamBufferCapacity = 100;
    })
    .AddCircuitOptions(options =>
    {
        // 缩短断开电路的保留时间,快速释放资源
        options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
        // 限制保留的最大电路数,避免内存占用过高
        options.MaxRetainedCircuits = 80;
    });

2. IIS应用池优化

  • 配置应用池回收规则:当内存占用超过6GB时自动回收,防止内存泄漏导致的进程崩溃
  • 调整应用池队列长度至2000,应对多用户并发请求
  • 确认IIS已正确安装WebSocketModule(在IIS管理器“模块”中检查)

三、组件生命周期修复

针对RadzenContextMenu在Dispose时触发的异常,需处理电路断开后的JS互操作调用:

1. 封装安全的JS互操作方法

替换组件中直接的JS调用,增加电路状态检查:

public static class SafeJSRuntimeExtensions
{
    public static async Task SafeInvokeVoidAsync(this IJSRuntime jsRuntime, string identifier, params object[] args)
    {
        if (jsRuntime is RemoteJSRuntime remoteJSRuntime && !remoteJSRuntime.Circuit.IsConnected)
        {
            return;
        }
        await jsRuntime.InvokeVoidAsync(identifier, args);
    }
}

若使用自定义组件,将InvokeVoidAsync替换为SafeInvokeVoidAsync;若使用Radzen组件,建议升级至最新版本,查看是否已修复该Dispose场景的问题。

2. 监听电路状态

注册CircuitHandler监听电路断开事件,及时取消未完成的异步操作:

public class CircuitConnectionHandler : CircuitHandler
{
    public override Task OnCircuitDisconnectedAsync(Circuit circuit, CancellationToken cancellationToken)
    {
        // 可在此处通知全局组件电路已断开,取消相关异步任务
        return base.OnCircuitDisconnectedAsync(circuit, cancellationToken);
    }
}

// 在Program.cs中注册
builder.Services.AddScoped<CircuitConnectionHandler>();
builder.Services.AddSingleton<CircuitHandler>(sp => sp.GetRequiredService<CircuitConnectionHandler>());

四、日志补充排查

启用SignalR详细日志,定位连接断开的具体原因:
在appsettings.json中添加日志配置:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.SignalR": "Debug",
      "Microsoft.AspNetCore.Http.Connections": "Debug",
      "Microsoft.AspNetCore.Components.Server.Circuits": "Debug"
    }
  }
}

通过日志可查看SignalR连接的建立、心跳、断开全流程,判断是客户端网络问题还是服务器端资源不足导致的中断。


内容的提问来源于stack exchange,提问作者Tim Kruger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 18:43:14