记录 redis 端口的坑,高并发请求常见的问题分类

Redis 连接池配置不当导致 TIME_WAIT 暴涨、端口被打满的排查与优化

前言

最近线上服务出现了一个比较典型的问题------服务器端口被打满,导致新连接无法建立。排查后发现根因是 Redis 客户端连接池配置不合理,产生了大量短连接,进而导致 TIME_WAIT 状态的连接持续堆积。

这里记录一下整个排查和优化过程,希望能帮到遇到类似问题的同学。

问题现象

线上告警显示服务出现连接异常,登录服务器后通过 netstat 统计 TIME_WAIT 状态的连接数:

bash 复制代码
netstat -ant | awk '$6=="TIME_WAIT"{c++} END{print c}'

多次执行后发现,TIME_WAIT 连接数在持续攀升:

复制代码
22644
22934
23499
22640
22775
24984
25503
26096
25853
26123
26630
27101
27518
27791
27146
27327
27858
28190
28638
28033

22k 一路涨到 28k+ ,而且没有回落趋势。Linux 默认的本地端口范围是 32768~60999,大约 28000 个端口,此时已经接近打满。

原因分析

排查发现问题出在 Redis 客户端的连接池配置上。原来的配置如下:

go 复制代码
RdbClient = redis.NewClient(&redis.Options{
    Addr:         host + ":" + port,
    Password:     pass,
    DB:           db,
    PoolSize:     100,
    MinIdleConns: 10,
    MaxIdleConns: 20,
})

这个配置存在几个关键问题:

1. PoolSize 过小

PoolSize: 100 意味着连接池最多持有 100 个连接。在高并发场景下,100 个连接远远不够用。当池内连接全部被占用时,客户端会创建新的连接来处理请求,而这些临时连接用完就关闭,变成了短连接。

2. 空闲连接管理不合理

MinIdleConns: 10MaxIdleConns: 20 让连接池对空闲连接的保留非常"吝啬"。大量连接在空闲后迅速被回收,等下一波请求来了又得重新建连,造成连接的频繁创建和销毁

3. 缺少空闲超时配置

没有设置 ConnMaxIdleTime,导致空闲连接的生命周期管理缺失。

核心矛盾

连接池容量不足 + 空闲连接回收过激 → 大量短连接 → TCP 四次挥手后进入 TIME_WAIT → TIME_WAIT 堆积 → 端口耗尽

简单回顾一下 TCP 的 TIME_WAIT 机制:主动关闭连接的一方会进入 TIME_WAIT 状态,默认持续 2 × MSL(通常 60 秒)。在这段时间内,这个端口是不可复用的。所以短连接越多,TIME_WAIT 堆积越严重。

优化方案

调整后的 Redis 客户端配置:

go 复制代码
RdbClient = redis.NewClient(&redis.Options{
    Addr:               host + ":" + port,
    Password:           pass,
    DB:                 db,
    PoolSize:           poolSize,          // 可配置,按实际负载调整
    MinIdleConns:       0,                 // 不强制维护空闲连接
    ConnMaxIdleTime:    idleTimeout,       // 空闲连接超时释放
    MaxActiveConns:     poolSize * 2,      // 限制最大活跃连接数
    MaxConcurrentDials: 10,                // 限制并发建连数
})

逐项说明:

参数 调整内容 目的
PoolSize 固定值 → 可配置变量 根据业务实际并发量灵活调整
MinIdleConns 10 → 0 避免维护不必要的空闲连接,减少资源浪费
ConnMaxIdleTime 无 → idleTimeout 让空闲连接有序超时释放,而非突然被回收后又立即重建
MaxActiveConns 无 → poolSize * 2 给活跃连接加上天花板,防止突发流量下无限制创建新连接
MaxConcurrentDials 无 → 10 限制并发建连的协程数,避免瞬间大量 dial 造成系统抖动

关键思路就是:提高连接复用率,减少短连接的产生。

效果

优化上线后,TIME_WAIT 连接数明显下降并趋于稳定,端口耗尽的问题不再出现。

小结

几个 takeaway:

  • Redis 连接池的 PoolSize 一定要根据实际并发量合理设置,不要拍脑袋给个固定小值
  • MinIdleConnsMaxIdleConns 配置不当会导致连接频繁创建销毁,反而得不偿失
  • 别忘了配置 ConnMaxIdleTime,让空闲连接的回收有章可循
  • MaxActiveConns 可以作为最后一道防线,防止连接数失控
  • 遇到端口耗尽问题,先用 netstat 看 TIME_WAIT 数量,往往就能找到方向

希望这篇排查记录能对你有所帮助,如果有更好的优化思路,欢迎在评论区交流 🙌

相关推荐
小码哥_常3 小时前
MyBatis-Plus:让数据库操作飞起来的神器
后端
2301_811274314 小时前
基于SpringBoot的智能家居管理系统
spring boot·后端·智能家居
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
舒一笑4 小时前
我把设备指纹生成逻辑拆开了:它到底凭什么区分不同设备?
后端·程序员·掘金技术征文
Nicander4 小时前
多数据源下@transcation事务踩坑
java·后端
郑州光合科技余经理4 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
sjsjsbbsbsn5 小时前
大模型核心知识总结
java·人工智能·后端
Moment6 小时前
2026 年,AI 全栈时代到了,前端简历别再只写前端技术了 🫠🫠🫠
前端·后端·面试
白晨并不是很能熬夜7 小时前
【PRC】第 2 篇:Netty 通信层 — NIO 模型 + 自定义协议 + 心跳
java·开发语言·后端·面试·rpc·php·nio
zshs0007 小时前
#从偶发无字幕到补偿探测链路:一次 B 站字幕导入问题的完整收敛过程
java·后端·重构