Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully.....

在CentOS7环境下,一个部署在Tomcat 8.5上的项目遇到问题,当长时间未访问后,再次打开页面出现白屏,需要刷新才能加载数据。通过检查服务器的日志,发现是由于MySQL的连接超时(wait_timeout)导致C3P0连接池资源被释放。解决方案是在jdbc.properties中添加'autoReconnect=true'参数,确保连接在断开后能自动重连,从而修复了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近将之前的项目部署到了服务器之后,发现在长时间不访问网站后,再次打开页面会出现白屏现象,除非重新刷新页面,否则无法正常加载数据,使用F12查看请求返回的JSON数据发现提示内部错误,由此可知问题在服务端。

服务器相关信息:

OS:CentOS7

MySql:5.7

Tomcat:8.5

登录服务器,依次检查Nginx、Tomcat、Redis、MySql服务的运行状况,使用如下命令:

ps -ef|grep {服务名称}

检查后一切正常,下一步我们需要从日志文件入手,进入Tomcat安装目录,我这里使用了Tomcat压缩包解压的方式,因此只需要进入logs目录下即可(根据自己安装的实际目录寻找就行):

cd /resources/apache-tomcat-8.5.54/logs/

查看catalina.out文件内容,注意:此文件内容即为在Windows下使用IDE开发工具时Tomcat实时输出的内容,可以帮助我们快速定位问题。

cat catalina.out

发现异常信息如下:

Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 426,962,099 milliseconds ago. The last packet sent successfully to the server was 426,962,100 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.;

通过内容可知,由于太久没有使用C3P0的连接池,超过了最大的有效时间,因此连接池资源被释放,MySql无法获得有效的资源,因此也无法取得数据。

知道了问题,那么解决也很容易,异常信息中也提供了解决方案,也就是说我们可以在mysql连接中添加autoReconnect属性来避免这个问题。

or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

 由于我的项目在服务器上,使用war包的方式来部署,因此需要修改相关信息就需要重新生成war包或者对当前war包内的配置修改,为了方便起见直接进入Tomcat的webapps目录对war包修改,(这里我的war包名称为o2o,使用时替换为你自己的项目名称)

cd /resources/apache-tomcat-8.5.54/webapps/o2o/WEB-INF/classes

修改jdbc.properties的内容

vim jdbc.properties

在文件最后添加autoReconnect=true,多个参数之间使用&连接。(若为本地IDE开发,直接修改对应jdbc配置文件内容即可。) 

jdbc.url = jdbc:mysql://{yourIpAddress}:3306/o2o?useUnicode=true&autoReconnect=true

 至此问题修复完成。

### 解决方案 `com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure` 表示 JDBC 客户端无法与 MySQL 数据库服务器建立有效的通信链接。以下是可能导致该问题的原因及其对应的解决方案: #### 1. **网络连接问题** 如果客户端和数据库之间的网络不稳定或者不可达,则可能会引发此异常。可以通过以下方式验证并解决问题: - 使用 `ping` 命令确认目标主机可达性。 - 测试 TCP/IP 连接是否正常,可以使用工具如 telnet 或 netstat 来检查指定端口(默认为 3306)的状态[^2]。 #### 2. **防火墙或安全组设置** 防火墙规则可能阻止了外部访问数据库的请求。需确保允许来自客户端 IP 地址的流量通过特定端口(通常是 3306)。对于云服务中的实例,还需调整相应的安全组策略[^4]。 #### 3. **MySQL Server 配置错误** 检查 MySQL 服务器配置文件 (`my.cnf`) 中 bind-address 参数是否正确设置了监听地址,默认情况下可能是仅限 localhost 访问。将其修改为实际网卡IP或设为 0.0.0.0 后重启服务生效[^3]。 #### 4. **驱动版本兼容性** 确认使用的 MySQL Connector/J 版本与当前安装的 MySQL Server 版本相匹配。不兼容的组合也可能导致此类异常发生。建议下载最新稳定版驱动程序替换旧版本[^2]。 #### 5. **超时参数优化** 调整连接字符串中的 timeout 设置以适应较差网络条件下的延迟情况。例如增加 connectTimeout 和 socketTimeout 的值可以帮助缓解瞬态断开的情况[^1]: ```java jdbc:mysql://<host>:<port>/<database>?connectTimeout=10000&socketTimeout=30000 ``` #### 6. **数据库连接池管理不当** 当应用程序频繁创建销毁大量短生命周期连接而未及时关闭资源时容易耗尽可用的最大连接数限额从而触发异常。合理配置数据源对象属性如 maxActive,minIdle,maxWaitTime 等有助于改善性能表现同时减少不必要的重连尝试次数[^5]: ```properties spring.datasource.hikari.maximum-pool-size=20 spring.datasource.hikari.idle-timeout=300000 spring.datasource.hikari.max-lifetime=1800000 ``` 另外注意避免长时间运行的大事务锁定过多表结构影响其他并发查询效率造成阻塞现象加剧最终形成恶性循环直至崩溃退出[^5]. --- ### 示例代码片段展示如何优雅处理潜在风险场景: 下面给出一段基于 Spring Boot 的 JdbcTemplate 实现批量插入操作的同时兼顾细粒度控制单条记录写入逻辑防止整体失败回退全部变更内容的例子说明最佳实践之一: ```java @Service public class BatchInsertService { private final JdbcTemplate jdbcTemplate; public BatchInsertService(JdbcTemplate jdbcTemplate){ this.jdbcTemplate = jdbcTemplate; } /** * 对每一条数据单独开启事务,即使部分失败也不会影响已成功的提交. */ @Transactional(propagation = Propagation.REQUIRES_NEW) public void insertData(String data){ String sql = "INSERT INTO example_table(column_name) VALUES (?)"; jdbcTemplate.update(sql,data); } } ``` 调用方只需简单遍历集合逐项传递给上述方法即可完成任务无需额外关注内部细节实现. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值