redis 连接池耗尽经常导致redis客户端连接数波动异常问题解决1.原配置修改之前 !-- 连接池配置 -- bean idjedisPoolConfig classredis.clients.jedis.JedisPoolConfig !-- 最大连接数 -- property namemaxTotal value200 / !-- 最大空闲连接数 -- property namemaxIdle value200 / !-- 每次释放连接的最大数目 -- property namenumTestsPerEvictionRun value1024 / !-- 释放连接的扫描间隔毫秒 -- property nametimeBetweenEvictionRunsMillis value30000 / !-- 连接最小空闲时间 -- property nameminEvictableIdleTimeMillis value1800000 / !-- 连接空闲多久后释放, 当空闲时间该值 且 空闲连接最大空闲连接数 时直接释放 -- property namesoftMinEvictableIdleTimeMillis value10000 / !-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -- property namemaxWaitMillis value1500 / !-- 在获取连接的时候检查有效性, 默认false -- property nametestOnBorrow valuetrue / !-- 在空闲时检查有效性, 默认false -- property nametestWhileIdle valuetrue / !-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -- property nameblockWhenExhausted valuefalse / /bean2.修改后修改之后 !-- 连接池配置 -- bean idjedisPoolConfig classredis.clients.jedis.JedisPoolConfig !-- 最大连接数根据实际压测调整建议 150 左右 -- property namemaxTotal value100 / !-- 最大空闲连接数与 maxTotal 保持一致避免频繁创建销毁 -- property namemaxIdle value100 / !-- 最小空闲连接数保底连接应对突发流量 -- property nameminIdle value10 / !-- 每次驱逐检查的连接数适当降低 -- property namenumTestsPerEvictionRun value50 / !-- 驱逐扫描间隔30 秒 -- property nametimeBetweenEvictionRunsMillis value30000 / !-- 设为 -1避免硬驱逐破坏 minIdle -- property nameminEvictableIdleTimeMillis value-1 / !-- 空闲超过该值且当前空闲连接数minIdle 时释放 -- property namesoftMinEvictableIdleTimeMillis value60000 / !-- 获取连接最大等待时间3 秒 -- property namemaxWaitMillis value3000 / !-- 关闭 testOnBorrow减少 PING 命令 -- property nametestOnBorrow valuefalse / !-- 开启空闲检测定期剔除无效连接 -- property nametestWhileIdle valuetrue / !-- 连接耗尽时阻塞等待而不是直接抛异常 -- property nameblockWhenExhausted valuetrue / /bean二、Jedis 连接池前后配置对比 连接数、连接生命周期变化分析先整理核心参数变更清单再分维度讲连接数量、空闲连接、新建 / 销毁、获取连接行为的变化最后总结线上表现差异。一、参数完整变更对照表参数修改前修改后变更影响核心说明maxTotal200100全局最大连接上限减半整个池子最多只能持有 100 条 TCP 连接maxIdle200100空闲连接上限同步减半池子不会保留超过 100 条空闲连接minIdle无配置默认 010新增最小空闲保底池子会主动维持至少 10 条空闲连接应对突峰numTestsPerEvictionRun102450每次后台驱逐线程扫描连接数大幅降低减少大量 PING 扫描开销minEvictableIdleTimeMillis180000030 分钟-1关闭「强制驱逐空闲连接」硬阈值不再单纯靠空闲时长销毁连接softMinEvictableIdleTimeMillis10s60s软驱逐空闲阈值拉长到 1 分钟仅当空闲连接 minIdle (10) 时才会释放超时空闲连接maxWaitMillis1500ms3000ms获取连接等待超时翻倍排队拿连接允许等待更久testOnBorrowtruefalse拿连接时不再发 PING 校验减少 Redis 命令开销但拿到死连接概率小幅上升testWhileIdletruetrue不变后台线程定期校验空闲连接有效性blockWhenExhaustedfalsetrue连接打满时策略反转原直接抛异常现阻塞等待 maxWait 时长再超时二、Redis 客户端连接数相关变化分 4 个维度全局最大 TCP 连接总量上限大幅下降修改前池子最多创建 200 条 Redis TCP 连接修改后上限压缩为 100 条现象client list 看到的客户端总连接峰值直接减半Redis 服务端连接占用更低。空闲连接数量变化最关键改动1保底空闲新增常驻 10 条连接修改前无 minIdle空闲连接可能被全部驱逐到 0流量突增时需要频繁新建 TCP 连接修改后池子后台会自动补连接始终保证至少 10 条空闲就绪连接突发流量不会大量新建连接。2空闲连接上限从 200→100池子不会堆积超过 100 条空闲连接避免大量闲置 TCP 占用 Redis 文件句柄。3空闲连接销毁逻辑彻底改变旧逻辑空闲超过 30 分钟 → 直接强制销毁不管当前池子缺不缺连接空闲超 10 秒且空闲数 200 → 释放容易出现低峰期连接被大量清到 0高峰期疯狂建连接。新逻辑minEvictableIdleTimeMillis-1取消 30 分钟强制销毁仅满足两个条件才销毁空闲连接① 空闲时长超过 60 秒② 当前空闲连接数 minIdle (10)效果低峰期最少保留 10 条空闲不会清空只有空闲连接多于 10 条、且闲置满 1 分钟才会慢慢释放多余连接连接复用率大幅提升TCP 新建 / 断开次数显著减少。4空闲扫描压力降低旧每次驱逐扫描 1024 个连接大量 PING 命令压 Redis新每次只扫描 50 条后台校验开销骤降Redis CPU 更低。流量高峰时新建连接、排队行为变化1连接耗尽策略反转 blockWhenExhausted旧blockWhenExhaustedfalse池子达到 maxTotal (200) 后立刻抛出 NoSuchElementException请求直接失败不会排队新blockWhenExhaustedtrue池子打满 100 条后新请求会排队等待空闲连接释放最多等 3 秒超时才报错表现高峰期不会瞬时大量报错请求排队缓冲但极端高并发下会出现接口耗时拉高。2获取连接等待时间变长maxWait 从 1.5s → 3s排队拿连接容错窗口更大降低瞬时并发报错率。连接有效性校验对连接存活的影响旧testOnBorrowtrue每次拿连接先 PING 校验无效直接丢弃、新建连接死连接会即时清理但每次请求多一条 Redis 命令性能损耗大新testOnBorrowfalse仅靠 testWhileIdle 后台巡检清理无效连接减少 PING 开销但极端场景下可能拿到已断连的 TCP执行命令时报连接异常业务需要捕获重试后台驱逐线程每 30 秒扫描会逐步剔除失效空闲连接不会长期堆积死连接。三、整体连接侧线上表现总结Redis 服务端总连接数峰值减半文件句柄占用更低低峰期不会清空空闲连接常驻 10 条保底减少 TCP 频繁创建销毁多余空闲连接销毁更温和只有闲置 1 分钟且超过 10 条才释放连接复用率更高连接打满时不再快速报错改为最多阻塞 3 秒等待空闲连接减少大量 PING 校验命令降低 Redis CPU 消耗后台扫描连接数量减少驱逐逻辑更轻量化风险点最大连接从 200 降到 100若业务真实并发超过 100会出现大量请求排队、接口延迟上升需压测确认 100 连接是否满足业务峰值。四、潜在风险提醒连接数相关maxTotal 下调至 100若业务并发高会出现排队等待连接接口 RT 上涨testOnBorrow 关闭后存在极低概率拿到断连连接业务需做好 Redis 异常重试softMinEvictableIdleTimeMillis 延长至 60s流量低谷会保留更多空闲 TCP短期占用 Redis 连接但换来了更少的重连开销。三、帮我解释一下修改之前客户端连接池波动非常大我们有39个节点修改之前有的时候客户端连接数突然变成几千然后降下来经常这样修改之后呢平稳在1300左右没有大幅度波动了。不知道什么原因一、先搞懂旧配置为什么会暴涨到几千连接、剧烈波动你们 39 个服务节点每个节点旧配置maxTotal200理论总上限 39*2007800这是基数但真正导致瞬间冲几千、反复震荡的核心是 4 个参数缺陷1. 旧驱逐逻辑会把空闲连接全部清 0流量一上来疯狂新建连接旧配置minIdle未配置默认 0minEvictableIdleTimeMillis180000030 分钟强制驱逐softMinEvictableIdleTimeMillis10000仅空闲 maxIdle 才释放行为拆解业务低峰、流量下滑后后台驱逐线程会持续清理空闲连接只要一条连接空闲满 30 分钟不管池子需不需要直接销毁没有最小空闲保底最后池子空闲连接会被清到 0流量突然上涨定时任务、峰值接口、批量查询池子里面一条可用连接都没有只能瞬间大批量新建 TCP 连接短时间内几百个新建连接打到 Redis多节点叠加客户端连接数瞬间飙升几千流量回落连接又慢慢被驱逐销毁数字断崖下跌形成大幅波动。2.blockWhenExhaustedfalse连接耗尽直接抛异常业务重试放大建连旧配置blockWhenExhaustedfalse池子连接打满 200 后新请求不排队、直接报错。 业务代码捕获 Redis 异常后大多会做重试逻辑重试又会再次向池子申请连接恶性循环 瞬时大量新建连接 → Redis 连接数暴涨 → 连接耗尽 → 大量报错重试 → 继续新建连接峰值直接拉满。3.testOnBorrowtrue每次拿连接 PING断连即时销毁加剧反复创建每次获取连接都发 PING 校验只要 TCP 失效立刻丢弃这条连接。 网络抖动、Redis 短暂卡顿、防火墙空闲断连时大量连接被当场销毁池子瞬间缺连接又要批量新建放大连接波动。4. numTestsPerEvictionRun1024驱逐线程扫描过猛频繁销毁空闲连接每次后台巡检一次性扫描 1024 条连接只要满足空闲阈值就批量销毁低峰期空闲连接被快速清空进一步加剧 “空池子 峰值爆建连” 的震荡。补充多节点叠加效应39 个业务节点每个节点池子独立。单个节点瞬间新建几十上百条连接39 个节点同时触发峰值Redisclient list看到总连接直接冲到几千流量回落又快速下跌波动极其明显。二、新配置为什么稳定卡在 1300 左右不再剧烈抖动新配置从保空闲、缓驱逐、排队限流、减少销毁四个维度根治波动逐条对应解决上面问题1. 新增 minIdle10池子永远保留保底空闲连接最核心稳连接手段每个节点强制常驻至少 10 条空闲连接低峰期驱逐线程不会把连接清到 0流量突增时直接复用现成空闲连接不需要大批量新建 TCP 从根源杜绝 “瞬间爆发式建连”连接总数不会脉冲式冲高。2. 关闭强制驱逐 minEvictableIdleTimeMillis-1只做温和软驱逐旧空闲 30 分钟强制销毁 新取消硬性销毁规则只有同时满足两点才释放多余连接 ① 空闲超过 60 秒② 当前空闲连接 minIdle (10) 效果 只会释放超出保底的多余空闲连接保底 10 条永远不动不会大面积清空池子连接数量不会断崖下跌。3. blockWhenExhaustedtrue连接打满排队等待消除异常重试风暴池子达到 maxTotal100 上限后新请求不再立刻报错而是阻塞等待最多 3 秒不会抛出大量 Redis 连接异常业务无异常就不会触发重试杜绝 “报错重试→疯狂新建连接” 的正反馈暴涨 并发流量平缓消化不会瞬间冲击 Redis 连接。4. testOnBorrowfalse减少连接即时销毁不再每次拿连接 PING网络轻微抖动不会批量丢弃有效连接 只有后台 testWhileIdle 定时巡检才清理失效连接连接销毁是缓慢、少量的不会短时间大量缺连接。5. numTestsPerEvictionRun50驱逐扫描轻量化每次只扫描 50 条连接低峰期不会一次性批量销毁大量空闲连接连接释放节奏平缓无断崖下跌。6. 单节点 maxTotal 从 200 降到 100总连接上限收窄峰值天花板降低单节点最大连接从 200 压缩到 10039 节点理论上限 39*1003900相比原来 7800 上限减半 同时有 minIdle 保底、排队机制削峰实际稳定运行总连接维持在 1300不会冲到几千。三、1300 稳定值怎么来的估算佐证39 个节点每个节点常态连接占用平均 1300 ÷ 39 ≈ 33 条 / 节点 每个节点保底空闲 10 条 业务活跃占用 20 多条合计三十多条完全符合新配置运行特征不会空池爆建连不会无限制堆积空闲连接打满会排队缓冲并发 整体总量被牢牢稳住无脉冲式暴涨暴跌。四、总结一句话因果旧配置无最小空闲、强制批量驱逐、连接耗尽直接报错触发重试、每次拿连接校验销毁失效连接低峰池子被清空峰值瞬间大批量新建连接39 节点叠加后连接数冲几千剧烈波动 新配置常驻 minIdle 保底连接、取消强制销毁、连接耗尽阻塞排队减少重试、轻量化驱逐逻辑流量起伏时无需瞬时大量新建 / 销毁连接总连接数被平滑控制在 1300 区间波动消失。今天 09:35如何解决连接耗尽直接抛异常的问题如何优化连接池配置以提高性能一句话因果旧配置无最小空闲、强制批量驱逐、连接耗尽直接报错触发重试、每次拿连接校验销毁失效连接低峰池子被清空峰值瞬间大批量新建连接39 节点叠加后连接数冲几千剧烈波动 新配置常驻 minIdle 保底连接、取消强制销毁、连接耗尽阻塞排队减少重试、轻量化驱逐逻辑流量起伏时无需瞬时大量新建 / 销毁连接总连接数被平滑控制在 1300 区间波动消失。今天 09:35如何解决连接耗尽直接抛异常的问题如何优化连接池配置以提高性能如何监控和管理连接池