记录 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 数量,往往就能找到方向

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

相关推荐
折七1 小时前
2026 年 Node.js 后端技术选型,为什么我选了 Hono 而不是 NestJS
前端·后端·node.js
Loo国昌2 小时前
【AI应用开发实战】09_Prompt工程与模板管理:构建可演进的LLM交互层
大数据·人工智能·后端·python·自然语言处理·prompt
Java后端的Ai之路3 小时前
【JDK】-JDK 17 新特性整理(比较全)
java·开发语言·后端·jdk17
沛沛rh453 小时前
Rust 中的三个“写手“:print!、format!、write! 的详细区别
开发语言·后端·rust
Loo国昌3 小时前
【AI应用开发实战】06_向量存储与EmbeddingProvider设计
人工智能·后端·python·语言模型·自然语言处理·prompt
白衣鸽子3 小时前
Java 线程同步-04:lock 机制
后端
加洛斯3 小时前
RabbitMQ入门篇(1):初识MQ
java·后端
苏三说技术4 小时前
Nacos 和 Apollo,哪个更好?
后端