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

如何使用Nginx实现Blazor Server负载均衡及会话持久化

Blazor Server集群Nginx负载均衡+无中断会话配置

Blazor Server默认通过WebSocket/长轮询维持Circuit(会话电路),状态默认存在单节点内存,仅配置普通负载均衡会出现会话漂移断连,只做简单会话粘滞也无法解决节点下线导致的用户被强制踢出问题,需要Nginx层和应用层配合配置,具体步骤如下:

Nginx层配置

Nginx侧采用Cookie注入方式实现会话粘滞,比IP_hash适配性更强(不会因为用户网络切换、IP变动导致粘滞失效),同时配置主动健康检查和故障重试,自动剔除异常节点。

注意:配置中用到的sticky指令依赖sticky模块,若你的Nginx未加载该模块,可替换为一致性哈希粘滞配置hash $cookie.AspNetCore.Session consistent;,基于Blazor自带的会话Cookie做路由哈希,不需要额外模块,只是故障转移时的会话迁移效率略低于sticky cookie方案。

完整配置示例如下:

http {
    # 定义Blazor后端节点池,替换为实际的服务器内网地址+端口
    upstream blazor_cluster {
        # 会话粘滞配置:Nginx给客户端种专用Cookie绑定后端节点,过期时间和应用会话超时对齐即可
        sticky cookie blazor_route_id expires=8h domain=你的站点域名 path=/ HttpOnly Secure SameSite=Lax;
        # 节点配置:max_fails和fail_timeout用于健康检查,连续3次失败则标记节点不可用,30秒后重新探测
        server 192.168.1.10:5000 weight=1 max_fails=3 fail_timeout=30s;
        server 192.168.1.11:5000 weight=1 max_fails=3 fail_timeout=30s;
        server 192.168.1.12:5000 weight=1 max_fails=3 fail_timeout=30s;
        # 长连接池配置,适配Blazor WebSocket长连接需求
        keepalive 128;
    }

    server {
        listen 443 ssl http2;
        server_name 你的站点域名;
        # 此处补全你的SSL证书配置即可
        # ssl_certificate /path/to/cert.pem;
        # ssl_certificate_key /path/to/key.pem;

        location / {
            proxy_pass http://blazor_cluster;
            # 基础代理头传递
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            # WebSocket支持必备配置
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            # 超时配置,需大于Blazor侧配置的Circuit空闲超时时间,避免Nginx主动断开长连接
            proxy_read_timeout 3600s;
            proxy_send_timeout 3600s;

            # 故障自动转移:后端节点报错、超时、不可用时,自动转发请求到其他可用节点
            proxy_next_upstream error timeout http_502 http_503 http_504;
            proxy_next_upstream_tries 3;
            proxy_next_upstream_timeout 10s;
        }
    }
}

应用层配套配置(节点下线无中断核心)

单靠Nginx配置无法解决节点下线后的会话接管问题,必须对Blazor应用做集群适配:

  • 共享DataProtection密钥
    所有集群节点必须共用同一套DataProtection密钥,否则登录Cookie、会话加密数据跨节点无法解密,会直接导致会话失效。在Program.cs中添加如下配置,将密钥存在共享Redis中:
    // 注册共享DataProtection,所有节点配置完全一致
    builder.Services.AddDataProtection()
        .PersistKeysToStackExchangeRedis(
            ConnectionMultiplexer.Connect("你的Redis连接字符串"), 
            "blazor-dataprotection-keys"
        )
        .SetApplicationName("你的Blazor应用固定名称");
    
  • 分布式存储Circuit会话状态
    默认Circuit存在单节点内存,节点下线后其他节点无法读取会话状态,需要替换为共享Redis存储:
    • 所有集群节点安装Nuget包Microsoft.AspNetCore.Components.Server.StackExchangeRedis
    • 修改Program.cs中的Blazor服务注册:
    builder.Services.AddServerSideBlazor()
        .AddCircuitOptions(options =>
        {
            // 断开的Circuit保留3分钟,给故障转移、节点切换留足够缓冲时间
            options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
            options.DetailedErrors = false;
        })
        // 注册Redis作为Circuit持久化存储,所有节点共用同一个Redis实例
        .AddStackExchangeRedisCircuitPersistence("你的Redis连接字符串");
    
  • 规范节点下线操作
    主动运维下线节点(比如发版、扩缩容)时,先在Nginx的upstream配置中给对应节点加down标记,重载Nginx配置后等待至少3分钟(和DisconnectedCircuitRetentionPeriod配置对齐),待节点上残留的活跃会话全部迁移完成后,再关闭应用进程,避免直接杀进程导致的瞬时断连。

配置校验规则

  • 正常访问站点时,打开浏览器开发者工具查看Cookie列表,能看到Nginx注入的粘滞Cookie(示例配置中名为blazor_route_id),多次刷新页面请求固定路由到同一后端节点,说明会话粘滞生效
  • 手动停止某一台后端节点的Blazor进程,对应节点上的已登录用户操作无感知、不会被踢出系统,刷新页面也能正常访问,说明故障转移生效
  • 切换客户端网络(比如WiFi切移动热点),会话保持登录状态、操作不中断,说明粘滞策略适配正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:12:15