mysql的交互式连接+非交互式连接超时时间设置和解释: Communications link failure The last packet successfully received from the server was XXX milliseconds ago
问题:
1.搭建了一个nginx反向的代理mysql db的TCP代理,实现用jar包去操作db操作数据库,发现执行业务执行时间太长(比如tc执行时间长)就会出现报错:Communications link failure The last packet successfully received from the server was XXX milliseconds ago
2.MySQL服务器有一个wait_timeout参数,它控制了非交互式连接的空闲超时时间 请问这个“非交互式连接的空闲超时时间” 是什么意思,能解释下“非交互式连接的空闲”的意思吗?
总结解决思路:
1. mysql 是长连接,在程序一启动(jar包被执行时,就会自动和mysql建议数据库连接), client就会建立和 mysql db的连接。 这个连接一致保持,直到程序执行结束时才会关闭。
所以方案一是:nginx里面TCP空闲连接超时时间(proxy_timeout参数),最好弄成永久不超时。 2.方案二:给DB 连接加心跳 :
在application.properity文件中配置: spring.datasource.hikari.connection-test-query=SELECT 1
我们首先需要理解MySQL中“交互式连接”和“非交互式连接”的区别。
交互式连接:通常指的是用户通过MySQL客户端(如mysql命令行的客户端)直接与服务器进行交互的连接。在这种连接中,用户输入一条命令,服务器返回结果,然后用户可能停顿一段时间再输入下一条命令。
非交互式连接:通常指的是由应用程序通过连接池、驱动程序(如JDBC)等建立的连接,用于执行查询并获取结果,而不需要人工干预。
那么,“非交互式连接的空闲超时时间”指的是:当一个非交互式连接在一段时间内(由wait_timeout参数指定,单位是秒)没有进行任何操作(即没有发送任何SQL命令)时,MySQL服务器会自动关闭这个连接。
这个机制是为了释放服务器上不必要的资源,因为维持一个空闲连接会占用内存和连接数资源。
举个例子:
假设wait_timeout设置为300(秒),那么如果一个非交互式连接在300秒内没有进行任何数据库操作,MySQL服务器就会断开这个连接。之后,如果应用程序尝试在这个已经关闭的连接上执行操作,就会收到一个连接错误。
在应用程序中,我们通常通过连接池来管理数据库连接,连接池可以配置为定期发送测试查询(如SELECT 1)以保持连接活跃,或者当连接被返回池中时重置其空闲时间,或者在从池中取出连接时检查连接是否仍然有效。

另外,MySQL还有一个参数interactive_timeout,用于控制交互式连接的空闲超时时间,其行为与wait_timeout类似,但适用于交互式连接。
注意:
在MySQL配置中,如果没有单独设置interactive_timeout,那么它会使用wait_timeout的值。但是,为了明确,通常建议两个参数都设置。
所以,当你的应用程序遇到“MySQL server has gone away”这样的错误时,有可能是因为连接空闲时间超过了wait_timeout而被服务器关闭了。
解决方法:
-
调整MySQL的wait_timeout和interactive_timeout参数,增加超时时间。
-
在应用程序的连接池配置中,设置一个比wait_timeout短的最大空闲时间,确保在连接被服务器关闭之前,连接池就会将其关闭并重建。
-
配置连接池定期进行连接有效性检查,例如使用测试查询。
MySQL连接类型详解
什么是"非交互式连接"
非交互式连接指的是应用程序通过编程接口(如JDBC、ODBC、PHP PDO等)与MySQL建立的连接,主要用于:
-
Web应用程序连接数据库
-
批处理作业
-
后台服务
-
脚本程序执行SQL
什么是"交互式连接"
交互式连接指的是用户通过客户端工具直接与MySQL交互:
-
MySQL命令行客户端(mysql -u -p)
-
MySQL Workbench
-
phpMyAdmin等图形化工具
-
用户手动输入SQL并查看结果
"空闲"的含义
空闲指的是连接建立后,在指定时间内:
-
没有执行任何SQL语句
-
没有数据包传输
-
连接处于"静默"状态
参数对比
| 参数 | 控制对象 | 默认值 | 适用场景 |
|---|---|---|---|
wait_timeout |
非交互式连接空闲超时 | 28800秒(8小时) | 应用程序连接 |
interactive_timeout |
交互式连接空闲超时 | 28800秒(8小时) | 命令行客户端 |
实际示例
1. 非交互式连接场景
前提:数据库的wait_timeout=600(10分钟),或者数据库的TCP反向代理设置的proxy_timeout=600s: (参考: https://www.cnblogs.com/pingguomang/p/19222365)
// Java应用程序 Connection conn = DriverManager.getConnection(url, user, password); // 连接建立 - 开始计时 // 执行查询 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users"); // 有数据交互 - 重置空闲计时器 // 接下来10分钟没有数据库操作 Thread.sleep(600000); // 此时如果wait_timeout=600(10分钟),连接会被服务器关闭 // 再次尝试使用连接会报错 stmt.executeQuery("SELECT * FROM orders"); // 抛出CommunicationsException
2. 查看和设置参数
-- 查看当前超时设置 SHOW VARIABLES LIKE '%timeout%'; SHOW VARIABLES WHERE Variable_name IN ('wait_timeout', 'interactive_timeout'); -- 设置全局超时(需要SUPER权限) SET GLOBAL wait_timeout = 600; -- 10分钟 SET GLOBAL interactive_timeout = 1800; -- 30分钟 -- 设置会话级超时 SET SESSION wait_timeout = 300; -- 仅当前连接生效
问题表现和影响
连接超时的错误现象
Communications link failure
The last packet successfully received from the server was XXX milliseconds ago
对应用程序的影响
-
连接池失效:连接池中的空闲连接被服务器关闭
-
应用报错:下次使用该连接时出现通信错误
-
性能下降:需要重新建立连接,增加开销
解决方案
1. 应用程序层面
// 连接池配置(HikariCP示例) HikariConfig config = new HikariConfig(); config.setMaximumPoolSize(20); config.setMinimumIdle(5); config.setIdleTimeout(300000); // 5分钟(小于MySQL的wait_timeout) config.setMaxLifetime(1800000); // 30分钟 config.setConnectionTestQuery("SELECT 1"); config.setValidationTimeout(5000);
2. 数据库层面优化
-- 合理的超时设置 SET GLOBAL wait_timeout = 600; -- 应用连接:10分钟 SET GLOBAL interactive_timeout = 1800; -- 交互连接:30分钟 -- 其他相关参数 SET GLOBAL net_read_timeout = 120; -- 读取超时 SET GLOBAL net_write_timeout = 120; -- 写入超时
3. 连接保持策略--这一点非常重要
// 定期执行轻量级查询保持连接活跃
@Scheduled(fixedRate = 300000) // 每5分钟执行一次
public void keepAlive() {
jdbcTemplate.execute("SELECT 1");
}
最佳实践建议
超时时间设置原则
# MySQL配置文件 my.cnf [mysqld] # 应用程序连接 - 根据业务特点设置 wait_timeout = 600 # 10分钟 # 交互式连接 - 可以设置更长 interactive_timeout = 3600 # 1小时 # 网络相关超时 net_read_timeout = 120 net_write_timeout = 120 connect_timeout = 10
连接池配置匹配
# 确保连接池超时 < MySQL超时 spring.datasource.hikari.max-lifetime=1800000 # 30分钟 < wait_timeout spring.datasource.hikari.idle-timeout=300000 # 5分钟 < wait_timeout
总结
"非交互式连接的空闲超时时间" 指的是:
-
非交互式连接:应用程序建立的数据库连接
-
空闲:连接建立后没有进行任何数据交互的状态
-
超时时间:MySQL服务器自动关闭空闲连接的等待时间
这个机制是为了释放服务器资源,防止长时间空闲连接占用内存和连接数。合理配置这个参数对于应用程序的稳定性至关重要。

浙公网安备 33010602011771号