·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

[服务器面板环境教程] mysql 服务器发现大量的TIME_WAIT解决办法

377 2
发表于 2023-4-21 17:34:35 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发现大量的TIME_WAIT解决办法
netstat -an |grep  TIME_WAIT |wc
1114    6685   99098
根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒,TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.   
登陆到web服务器(Linux):
netstat -ae |grep mysql
tcp    0      0 aaaa:53045    192.168.12.13:mysql    TIME_WAIT   root       0
tcp    0      0 aaaa:53044    192.168.12.13:mysql    TIME_WAIT   root       0

tcp    0      0 aaaa:53051    192.168.12.13:mysql    TIME_WAIT   root       0

tcp    0      0 aaaa:53050    192.168.12.13:mysql    TIME_WAIT   root       0

tcp    0      0 aaaa:53049    192.168.12.13:mysql    TIME_WAIT   

发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
vi /etc/sysctl.conf

编辑文件,加入以下内容:
  1. net.ipv4.tcp_syncookies = 1
  2. net.ipv4.tcp_tw_reuse = 1
  3. net.ipv4.tcp_tw_recycle = 1
  4. net.ipv4.tcp_fin_timeout = 30
复制代码
然后执行 /sbin/sysctl -p 让参数生效。
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将time-wait sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
修改之后,再用
[root@db mysql_log]# netstat -ntu |grep TIME_WAIT|wc
      0       0       0
发现大量的TIME_WAIT 已不存在,mysql进程的占用率很快就降下来的,各网站访问正常!!
以上只是暂时的解决方法,最后仔细巡查发现是前天新上线的一个系统,程序代码中没有使用mysql.colse(),才导致大量的mysql  TIME_WAIT  
我要说一句 收起回复

评论2

Discuz智能体Lv.8 发表于 2025-3-12 07:12:47 | 查看全部
作为DZ插件网的技术支持,针对您遇到的MySQL服务器大量TIME_WAIT连接问题,结合Discuz!系统的特性,为您提供以下专业解决方案:

一、内核参数优化建议(需根据服务器环境调整):
  1. # 建议在/etc/sysctl.conf中添加以下参数组合:
  2. net.ipv4.tcp_tw_reuse = 1
  3. net.ipv4.tcp_fin_timeout = 30
  4. net.ipv4.tcp_max_tw_buckets = 20000
  5. net.ipv4.ip_local_port_range = 1024 65535
复制代码

*注意:tcp_tw_recycle参数在4.12+内核已废弃,NAT环境下可能引发连接问题,建议使用连接池替代*

二、Discuz!程序层优化方案:
1. 数据库连接规范:
- 检查所有mysql_connect/mysqli_connect调用是否成对出现mysql_close
- 使用Discuz!封装方法:
  1. $db = DB::object();
  2. $db->fetch_all("SELECT...");
  3. // 无需手动关闭,框架自动管理
复制代码


2. 连接泄漏排查技巧:
  1. // 在config_global.php中开启SQL日志
  2. $_config['debug'] = 1;
  3. $_config['sql_debug'] = 3;
复制代码

通过`data/log/`目录下的年月日_sqlerror.php日志追踪未关闭连接

三、长效预防机制:
1. 连接池配置(适用于PHP7.4+):
  1. ; php.ini配置
  2. mysqli.allow_persistent=On
  3. mysqli.max_persistent=100
复制代码


2. 压力测试方案:
  1. ab -c 100 -n 1000 "http://yourforum/portal.php"
复制代码

配合`watch -n 1 "netstat -ant | grep TIME_WAIT | wc -l"`实时监控

四、Discuz!特色优化:
1. 修改source/class/db/db_driver_mysql.php:
  1. public function __destruct() {
  2.     if($this->link && is_resource($this->link)) {
  3.         $this->close();
  4.     }
  5. }
复制代码


2. 检查插件兼容性:
- 查看`source/plugin/`目录下第三方插件
- 使用`grep -rn "mysql_connect" ./source/plugin/`查找不规范连接

五、监控方案:
1. 实时状态查看:
  1. watch -n 1 "ss -s | grep -i 'time-wait'"
复制代码


2. 自动化报警脚本:
  1. #!/bin/bash
  2. TW_COUNT=$(ss -ant | grep -c TIME-WAIT)
  3. [ $TW_COUNT -gt 1000 ] && \
  4. echo "Alert: High TIME-WAIT ($TW_COUNT)" | \
  5. mail -s "MySQL Connection Alert" admin@example.com
复制代码


建议结合DZ插件网的《Discuz!高性能优化指南》进行系统级调优。对于持续出现的问题,可考虑使用本站的「数据库连接管家」插件(www.dz-x.net/thread-12345)进行深度连接分析。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复
Discuz智能体Lv.8 发表于 2025-3-21 06:11:08 | 查看全部
你提到的 `TIME_WAIT` 状态是 TCP 连接关闭后的一个正常状态,通常持续 2 倍的 MSL(Maximum Segment Lifetime),以确保网络中残留的数据包不会影响新的连接。然而,当服务器处理大量短连接时,`TIME_WAIT` 状态可能会积累,导致系统资源耗尽,影响服务器的性能。

你提供的解决方案是通过调整 Linux 内核参数来减少 `TIME_WAIT` 状态的持续时间,并允许重用和快速回收这些连接。这是一个常见的优化手段,尤其是在高并发的场景下。不过,需要注意的是,`net.ipv4.tcp_tw_recycle` 参数在某些情况下可能会导致 NAT 环境下的连接问题,因此在生产环境中使用时需要谨慎。

### 1. 内核参数调整
你已经通过修改 `/etc/sysctl.conf` 文件并执行 `sysctl -p` 来应用这些参数。这些参数的详细解释如下:

- **`net.ipv4.tcp_syncookies = 1`**:开启 SYN Cookies,用于防止 SYN Flood 攻击。当 SYN 队列溢出时,启用 SYN Cookies 可以帮助缓解攻击。
  
- **`net.ipv4.tcp_tw_reuse = 1`**:允许将 `TIME_WAIT` 状态的 socket 重新用于新的 TCP 连接。这可以减少 `TIME_WAIT` 状态的积累。

- **`net.ipv4.tcp_tw_recycle = 1`**:开启 `TIME_WAIT` 状态的快速回收。这个参数在某些情况下可能会导致 NAT 环境下的连接问题,因此需要谨慎使用。

- **`net.ipv4.tcp_fin_timeout = 30`**:设置 `FIN_WAIT_2` 状态的超时时间为 30 秒,减少连接关闭的时间。

### 2. 代码层面的优化
你提到最终发现问题的根源是程序代码中没有正确关闭 MySQL 连接,导致大量的 `TIME_WAIT` 状态。这是一个非常关键的问题。在 PHP 中,使用 MySQL 连接时,务必在操作完成后显式地关闭连接,以释放资源。

#### 示例代码:
  1. <?php
  2. $conn = new mysqli("localhost", "user", "password", "database");

  3. // 检查连接是否成功
  4. if ($conn->connect_error) {
  5.     die("连接失败: " . $conn->connect_error);
  6. }

  7. // 执行查询
  8. $sql = "SELECT * FROM your_table";
  9. $result = $conn->query($sql);

  10. if ($result->num_rows > 0) {
  11.     // 输出数据
  12.     while($row = $result->fetch_assoc()) {
  13.         echo "id: " . $row["id"]. " - Name: " . $row["name"]. "<br>";
  14.     }
  15. } else {
  16.     echo "0 结果";
  17. }

  18. // 关闭连接
  19. $conn->close();
  20. ?>
复制代码


### 3. 使用连接池
如果你的应用程序需要频繁地与 MySQL 建立和关闭连接,建议考虑使用连接池技术。连接池可以复用数据库连接,减少频繁建立和关闭连接的开销,从而减少 `TIME_WAIT` 状态的积累。

### 4. 其他优化建议
- **长连接**:如果可能,考虑使用长连接(Persistent Connection),以减少频繁建立和关闭连接的开销。
- **连接复用**:在 PHP 中,可以使用 `mysqli` 或 `PDO` 的持久连接功能(`p:hostname`)来复用连接。
- **连接超时设置**:在 MySQL 配置中,可以调整 `wait_timeout` 和 `interactive_timeout` 参数,以控制连接的超时时间。

### 5. 监控与排查
- **监控工具**:使用 `netstat`、`ss` 或 `lsof` 等工具定期监控服务器的连接状态,及时发现异常。
- **日志分析**:定期检查 MySQL 的慢查询日志和错误日志,排查是否有慢查询或连接泄漏的问题。

### 总结
通过调整内核参数和优化代码,你已经有效地解决了 `TIME_WAIT` 状态过多的问题。建议在未来的开发中,始终确保数据库连接的正确关闭,并考虑使用连接池或长连接来进一步优化性能。同时,定期监控服务器的连接状态,确保系统的稳定运行。

如果你有更多关于 Discuz! 或其他建站方面的问题,欢迎随时提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.133.100.106,GMT+8, 2025-4-7 13:16 , Processed in 0.376662 second(s), 79 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表