根本原因是会话未同步,负载均衡将用户请求轮询分发至不同服务器导致session丢失;解决需选共享session(如redis)或会话保持,后者依赖七层协议识别cookie且须确保健康检查全通过。

为什么加了负载均衡,用户却总被要求重新登录?
根本原因是会话(session)没同步,而负载均衡默认把同一用户的请求轮询分发到不同后端服务器。比如用户在 server-A 完成登录,但下一次请求被转发到 server-B,而 server-B 根本没存这个 session,自然就“掉线”了。
这不是代码写错了,而是架构设计中必须显式处理的环节。解决方向只有两个:要么让 session 在所有节点间共享(如存 Redis),要么让请求始终落到同一台机器上——后者就是「会话保持」,也是最快见效、改动最小的方案。
四层 vs 七层:选错协议,会话保持直接失效
四层(TCP/UDP)负载均衡只能靠源 IP 做哈希路由;七层(HTTP/HTTPS)才能读取 Cookie 或 Header 做更精准的粘性调度。如果你的应用走的是 HTTPS,但 LB 配的却是 TCP 监听器,那 jsessionid 或 ASP.NET_SessionId 这类 cookie 就完全看不见,会话保持形同虚设。
- 确认监听协议:HTTP/HTTPS 监听器才支持基于 Cookie 的会话保持
- 检查健康检查方式:HTTP 类型检查必须能正确返回 200,否则 LB 会把正常节点踢出,导致“保持”中途断开
- 源 IP 算法慎用:NAT、CDN、代理后客户端真实 IP 会被掩盖,
SOURCE_IP会误判成“同一个用户”或“多个用户”
怎么配才真正生效?关键参数和常见陷阱
以主流云厂商(华为云/京东云/Azure)为例,开启会话保持不只是点个开关,还得盯住几个硬性条件:
-
session_persistence字段不能为null,且需明确指定类型,如{"type": "HTTP_COOKIE", "cookie_name": "JSESSIONID"} - 超时时间别设太短:默认 1440 秒(24 分钟)是底线,低于这个值,活跃用户可能在操作中途就被重定向
- 后端服务器组必须已关联到监听器,且健康检查状态为
ONLINE;任一节点失联,LB 会临时绕过会话规则,把流量切走 - 如果用了 Ingress(K8s 场景),注意注解写法:
nginx.ingress.kubernetes.io/affinity: "cookie",不是所有 Ingress Controller 都支持sticky字段
会话保持不是银弹:什么情况下它反而会坏事?
当后端节点性能不均、或存在长连接/大文件上传等非典型请求时,强行绑定会导致负载严重倾斜。比如一个用户上传 2GB 视频,持续占用 server-A 的带宽和连接数,其他轻量请求全被堵死。
这时该关就关:会话持久性 = 无(Azure)、session_persistence = null(华为云 API),再配合应用层改造——比如把 session 存 Redis,并确保序列化兼容(Java 注意 Serializable 和 serialVersionUID)。
真正容易被忽略的,是健康检查与会话保持的耦合关系:只要有一个后端实例探测失败,整个 session stickiness 逻辑就会降级,用户瞬间“失联”。所以别只盯着 cookie 名,先看监控里 health_check.status 是不是全绿。










