负载均衡的 “粘性会话”,什么时候不该开

前段时间接手一个老服务的故障复盘,问题表象很迷惑:小部分用户时不时报请求超时,大部分用户访问正常,流量监控看整体 QPS、CPU、内存都稳稳的,看不出明显异常。

查了半天链路才锁定,是负载均衡上开启了会话保持,也就是大家常说的粘性会话。

当初开这个配置,是因为早期服务没有做状态剥离,会话信息存在单机内存里,用户请求必须落到同一台实例才能读到登录态。后来项目迭代,早就把会话迁到了 Redis,所有节点都是无状态的,但是负载均衡这边的配置没人关掉,就一直遗留下来了。

无状态服务还开粘性会话,隐患藏得很深。

首先是流量天然不均。如果一部分客户端固定绑死某一台实例,一旦这部分用户量慢慢涨起来,这台机器的负载会持续高于其他节点。别的节点 CPU 还在 30%,它已经跑到 80%,超时就集中在这一批用户身上。扩容的时候更尴尬,新增的实例很难分到流量,扩容基本等于白扩,负载均衡没法把流量均匀打散。

还有实例上下线的问题。滚动更新的时候,一部分用户绑定的旧实例被销毁,会话绑定关系失效,请求会重新调度。这个过程本身可以接受,但如果是批量重启,大量连接同时解绑、重新分配,短时间会出现一波集中报错。更麻烦的是健康检查剔除节点的时候,已经绑定到故障节点的连接,只要连接没断,LB 还会继续往故障实例转发请求。

很多人有个误区,觉得粘性会话只是一个兼容选项,开着也没坏处,大不了流量不均一点。实际上它直接破坏了无状态服务最核心的优势:弹性、容错、流量均分。

当然也不是说粘性会话一无是处,它有自己适合的场景。比如一些需要长连接、服务端内存缓存临时计算结果的业务,或者老旧的、暂时没法改造会话存储的单体应用,短期过渡可以启用。但只要业务已经改成无状态,优先关掉,用一致性哈希或者轮询,比依赖会话绑定稳妥得多。

我们当时的处理也简单,分灰度关掉会话保持,观察一两天错误曲线,超时报错直接消失,各个实例的负载也拉平了。顺便在 wiki 上加了一条规范:新服务上线默认关闭粘性会话,开启必须写清楚理由和下线时间,避免以后再出现这种配置遗留。

很多负载均衡层面的故障,都不是复杂算法问题,而是早年为了兼容写的配置,业务改了,配置没人同步清理,慢慢埋成定时炸弹。

相关推荐
我喜欢就喜欢1 小时前
豆包赋能抖音内容创作与运营实战指南
人工智能·1024程序员节
奕鼎竜瑆1 小时前
「蚂蚁灵波具身大模型挑战赛」上篇 | 从零到 56.8%:一个人、一张卡、一场具身智能比赛的完整配置
1024程序员节
JavaPub-rodert1 小时前
王仕宇开源的 JavaPub Tools:从 JSON 格式化工具到开发者在线工具箱,打开即用、数据本地处理
1024程序员节
4SAPI1 小时前
AI 数据分析工具大模型 API 选型指南
大数据·人工智能·架构·php·1024程序员节
paopaokaka_luck2 小时前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
无限码力2 小时前
拼多多校招笔试真题 10.18 - 甲乙指示灯链(C++/Py/Java /Js/Go)
1024程序员节·pdd·拼多多笔试真题·拼多多技术岗笔试真题·拼多多秋招笔试真题·拼多多校招笔试真题
andrsted2 小时前
练题簿在线免费刷题:让整理过的资料,变成能反复练习的题库
学习·微信小程序·小程序·学习方法·刷题·1024程序员节
2601_952047792 小时前
分步式调出单同步:金蝶云星空到MySQL的实战拆解
1024程序员节
伟大的前程2 小时前
8051 FLASH架构
1024程序员节