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

Blazor Server在负载均衡场景下如何跨服务器传递对象?

Blazor Server多服务器负载均衡下的事件处理问题

首先纠正一个核心误解:你代码里的employee对象并没有存在会话数据中,Blazor Server的组件状态(包括循环里的employee引用)是保存在**服务器端的Circuit(电路)**里——每个客户端和服务器建立的SignalR连接对应一个专属Circuit,组件实例、状态默认都存在单台服务器的内存中。

针对你的问题逐一说明:

1. 请求发到无对应Circuit的服务器会发生什么?

如果负载均衡没配置粘性会话(会话保持),点击按钮的事件请求被路由到另一台服务器时,这台服务器没有当前客户端的Circuit数据,会直接抛出CircuitNotFoundException,前端会出现连接断开提示,甚至整个Blazor应用会重启,用户之前的操作状态全部丢失。

2. 是否完全依赖HTTPS会话保持?

是的,默认情况下必须配置粘性会话(不管是基于Cookie还是IP的会话保持规则),才能让同一个客户端的所有SignalR请求(包括事件回调)都发到同一台服务器,这样才能找到对应的Circuit,保证事件处理能拿到正确的employee对象。

3. 故障转移场景下新服务器接收请求会怎样?

如果原服务器故障,负载均衡把请求转到新服务器,新服务器同样没有原客户端的Circuit数据,会触发和上面一样的错误:Circuit找不到,前端连接断开,应用重启,用户需要重新进行操作。

可行的优化方案

  • 摆脱Circuit对象依赖:点击按钮时只传递employee.Id,在HandleDelete方法里重新从数据库或分布式缓存中查询员工数据,这样不管请求到哪台服务器,都能通过ID获取到目标数据。修改后的代码示例:
@foreach (var employee in Employees)
{
    <tr>
        <td class="btn-group-sm">
            <button class="btn btn-outline-danger"
               @onclick="() => HandleDelete(employee.Id)">
               Delete
            </button>
        </td>
    </tr>
}

@code {
    private async Task HandleDelete(Guid employeeId)
    {
        var employee = await _employeeRepository.GetByIdAsync(employeeId);
        // 执行删除逻辑
    }
}
  • 配置分布式Circuit存储:使用Blazor Server的分布式Circuit支持(比如用Redis作为Circuit存储介质),让所有服务器共享Circuit数据,这样无需依赖粘性会话,任意服务器都能找到对应Circuit和组件状态。

内容的提问来源于stack exchange,提问作者David Thielen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:37:34