一.前言
这个错误很诡异, 困扰了我一周左右, 很苦恼,很烦躁, 如鲠在喉,不吃不快啊! 当然忙别的时候也会忘掉这个苦恼和烦躁. 因为虽然报错了,但是不影响程序的任何使用, 这就奇怪了, 如果非要说影响, 那就是"占着茅坑不拉屎", 一直在服务器控制台霸屏. 如果你也有类似的问题, 或者对着问题感兴趣, 那请继续看下去, 精彩的在后面.
二.报错信息
Exception in thread "vertx-jdbc-service-get-connection-thread" java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:975)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109)
at io.vertx.ext.jdbc.impl.JDBCClientImpl.lambda$getConnection$3(JDBCClientImpl.java:197)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这个报错信息, 以50.36秒左右的频率打印一次, 别问我这个时间从哪里来的, 问了我也不会告诉你我是用手机计时器统计出来的. 从报错信息可以看出, vertx的一个线程获取connection连接失败, 因为dataSourceClassName or jdbcUrl没有配置. 主要就是这个意思.
三.问题分析
public static DataSource getHikariDataSource(JsonObject cofig) {
_LOG.info("getHikariDataSource,config:{}",cofig.toString());
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(cofig.getString("url"));
ds.setUsername(cofig.getString("username"));
ds.setPassword(cofig.getString("password"));
ds.setConnectionTestQuery(cofig.getString("connectionTestQuery", "SELECT 1"));
ds.setConnectionTimeout(cofig.getLong("connectionTimeout", 30000L));
ds.setIdleTimeout(cofig.getLong("idleTimeout", 600000L));
ds.setMaxLifetime(cofig.getLong("maxLifetime", 1800000L));
ds.setMaximumPoolSize(cofig.getInteger("maximumPoolSize", 10));
ds.setMinimumIdle(cofig.getInteger("minimumIdle", 10));
//ds.setLeakDetectionThreshold(30000); //connection泄漏检测
return ds;
}
1.debug或者打印日志, 发现connection 里面都是有值的
2.程序在本地运行没有任何问题
3.程序在Linux服务器上运行也不影响任何接口的CRUD操作, 就是单纯的报错,让我们回顾一下这个错误信息
Exception in thread "vertx-jdbc-service-get-connection-thread" java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
综上所述: 在我抚摸了三个小时的刘海后, 我冷静并且精准地分析出了, 1.肯定不是配置dataSorce or jdbcUrl的问题, 因为如果配置出现问题, 接口根本就不能用. 2. 那就是你在设置数据源,设置数据库参数之前就调用连接了,正常人应该不会这样, 经过验证,我确实是个正常人. 3.那就是有人欺骗了你, 你看到的并不是真的. 当我正要在幻境中遨游的时候, 旁边的老王, 一句话把我带进了现实,"你个xx,摸够了没有, 就剩下三根刘海, 还摸." 是的,这个时候, 我就想有可能看到的报错信息,是别的进程输出的, 按照这个思路一路走下去, 最终发现了终极答案.
四.解决方法
1.日志全部都输出在 nohup.out中, 那就来看一看, 这个nohup.out都有谁在用, 在nohup.out所在的目录下,输入下面指令
指令和结果:
有三个进程在调用这个pid, 看到这个结果, 非常高兴, 证明方向应该是正确的.
2.查看自己程序的进程id是多少
指令和结果:
这就可以得出结论: 9392 和 9393 也在往nohup.out里面输出日志
3.来看看4324和9392和9393是什么进程
通过对比,相信机智的你, 应该能发现问题, 4324是正在运行的程序, 9392是脚本文件的一个程序, 9323可能是某次没有kill成功,然后一直在后台运行,往nohup.out输出日志,就出现了那种"输出着异常日志, 但是不影响任何使用"的诡异现象. 我每次运行程序, 都是先kill -9 pid, 然后 nohup sh start.sh & . 如果有知道出现这种问题的具体原因,并且以后可以更好的规避的大神, 欢迎留言,不吝赐教.
4.将这三个进程杀掉, 然后重新启动自己的程序
kill -9 4324
kill -9 9392
kill -9 9393
nohup sh start.sh &
OK, 完美运行!
五.总结
开发过程中,会遇到各种各样的问题, 调整心态, bug虐我千百遍, 我待bug如初恋. 终会有xxx的那一天的! 加油!