记一次使用hive-jdbc+tomcat-jdbc连接(Connection)中断的处理过程

当业务代码遍历大量Hive表信息时,遇到连接在4000+表时突然断开。通过日志分析,发现异常源于Hive-JDBC的libthrift,连接由Mybatis到Tomcat-JDBC逐级中断。问题定位为`removeAbandonedTimeout`配置,经过调整该参数,解决了6分钟后连接被自动关闭的问题。下一步计划研究为何在使用中的连接会被标记为abandoned。

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

现象描述

Hive环境一个数据库,拥有表8000+,业务代码需要挨个desc {tableName}来获取表信息。当程序运行到4000+左右,开始出现获取信息失败。

查找原因

通过查看日志发现是连接已断开,具体如下:

【INFO】org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.sql.SQLException: Connection has already been closed.
### The error may exist in 省略/HiveCollectionMapper.xml
### The error may involve 省略.HiveCollectionMapper.getTableParameters
### The error occurred while executing a query
### SQL: desc formatted logsget.`dim_qdas_superderive_eventlist`
### Cause: java.sql.SQLException: Connection has already been closed.
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:57)
	at com.sun.proxy.$Proxy365.getTableParameters(Unknown Source)
	...省略
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: Connection has already been closed.
	at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:117)
	at org.apache.tomcat.jdbc.pool.JdbcIn
### Hive 初始化时因缺少 MySQL JDBC 驱动导致的 `ClassNotFoundException` 的解决方案 #### 问题分析 当执行命令 `schematool -dbType mysql -initSchema` 来初始化 Hive 元数据库时,如果遇到错误提示 `java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver` 或者类似的 `com.mysql.jdbc.Driver` 错误,通常是因为以下原因之一: 1. **JDBC 驱动未正确加载**:尽管 lib 目录中有相应的 JAR 文件,但如果版本不匹配或者路径配置有误,仍然可能导致无法找到指定的 Driver 类。 2. **Driver 路径差异**:不同版本的 MySQL Connector/J 提供不同的 Driver 实现。例如,5.x 版本支持的是 `com.mysql.jdbc.Driver`,而 6.x 及以上版本则改为了 `com.mysql.cj.jdbc.Driver`[^1]。 --- #### 解决方案 ##### 方法一:确认并替换正确的 MySQL Connector/J 版本 - 确认当前使用的 MySQL Connector/J 是否与项目的 Driver 名称一致。如果是旧版 Hive 使用了较新的 MySQL Connector/J (6.x),可能会因为默认寻找 `com.mysql.jdbc.Driver` 导致失败。 - 下载对应版本的 MySQL Connector/J 并将其放置到 Hive 的 lib 目录下: - 对于 `com.mysql.jdbc.Driver`,应使用 MySQL Connector/J 5.x 版本。 - 对于 `com.mysql.cj.jdbc.Driver`,应使用 MySQL Connector/J 6.x 或更高版本。 ```bash wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-<version>.tar.gz tar -zxvf mysql-connector-java-<version>.tar.gz cp mysql-connector-java-<version>/mysql-connector-java-<version>-bin.jar $HIVE_HOME/lib/ ``` 确保删除可能存在的其他版本冲突文件[^4]。 --- ##### 方法二:修改 Hive 配置以适配新版本驱动 如果决定继续使用 MySQL Connector/J 6.x,则需调整 Hive 的配置文件 (`hive-site.xml`) 中的相关参数,使其指向新版 Driver: ```xml <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.cj.jdbc.Driver</value> </property> ``` 同时注意更新 URL 参数以兼容新特性(如 SSL 设置): ```xml <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?useSSL=false&serverTimezone=UTC</value> </property> ``` 上述更改可以避免因 Driver 不匹配引发的问题。 --- ##### 方法三:排查 ClassLoader 加载顺序 有时即使 JAR 存在于 `$HIVE_HOME/lib` 中,但由于 JVM 的类加载机制或其他容器环境的影响(比如 Tomcat),仍可能出现优先级较低的情况。可以通过以下方式验证和修复: - 执行查找命令定位所有可能影响的 JAR 文件位置: ```bash find / -name "mysql-connector-java*.jar" 2>/dev/null ``` - 若发现多个版本共存,建议清理掉不必要的老版本或低优先级路径下的 JAR 文件。 --- ##### 方法四:手动测试 JDBC 连接 为进一步排除潜在隐患,可以在独立环境中运行一段简单的 Java 测试代码来验证 JDBC 驱动是否正常工作: ```java import java.sql.DriverManager; import java.sql.Connection; public class TestMySQLConnection { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "password"; try { Connection conn = DriverManager.getConnection(url, user, password); System.out.println("Connected successfully!"); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 成功建立连接表明驱动无异常;反之可根据堆栈信息进一步诊断[^3]。 --- ### 总结 综合来看,解决此问题的关键在于明确所用 MySQL Connector/J 的具体版本及其对应的 Driver 类名,并妥善管理依赖关系以防冲突。按照前述方法逐一排查即可有效规避此类错误。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值