项目场景:
项目数据源迁移,springboot整合impala时,发现druid部分参数未被正常识别,导致impala会话失效或重启后,应用无法连接impala发生报错
druid版本是1.1.10
问题描述
具体错误可能有如下几种:
### Error querying database. Cause:java.sql.SQLException:[Cloudera][ImpalaJDBCDriver]
(500051)Error processing query/statement. Error code:0, SQL state: TStatus(statusCode:
ERROR_STATUS,sqlState:HY000, errorMessage:Invalid session id: d04e2043a21fedcc:
3f5634a7b2b56bbf
Caused by:com.cloudera.impala.support.exceptions.ErrorException:[Cloudera]
[ImpalaJDBCDriver](500593)Communication link failure. Failed to connect to server.
Reason:java.net.SocketException:Software caused connection abort:socket write error.
ExecuteStatment for query "select
第一种是impala的会话失效后,应用请求接口发生的错误,Invalid session(无效会话)
第二种是impala重启后,应用请求接口发生的错误,Failed to connect to server(无法连接至服务)
以上几种无非都是同一种原因,druid在发现连接不通时并没有销毁目前线程去重新创建连接
错误应该不止这几种的,但是导致这类错误的原因应该是差不多的
原因分析:
提示:这里填写问题的分析:
分析下原因:用druid连接池的小伙伴们都知道有两个参数是timeBetweenEvictionRunsMillis 和validationQuery ,那么第一个参数的含义是配置间隔多久才进行一次检测,检测需要关闭的空闲连接(单位毫秒),第二个则是验证连接可用,我们配置普通数据库的时候在配置文件中直接加入这两个参数即可,但目前的实际情况它们好像并没有起作用
经过一段时间测试,我发现当连接不可用时druid并没有校验其可用性,也没有关闭空闲连接,于是便从这里着手解决问题,先放出我的配置文件datasource部分的参数
注意我这里是整合了Oracle和Impala,以下所有数据库ip和库名皆为虚拟,自行替换即可
spring:
datasource:
app:
oracle:
driver-class-name: oracle.jdbc.OracleDriver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:oracle:thin:@//127.0.0.1:1521/test
username: root
password: root
druid:
initial-size: 5
min-idle: 5
maxActive: 20
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
impala:
url: jdbc:impala://127.0.0.1:21050/bigdate;AuthMech=3
driver-class-name: com.cloudera.impala.jdbc41.Driver
username: hive
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
解决方案:
提示:这里填写该问题的具体解决方案:
知道了问题原因接下来便是解决方案了,来看一下我的部分配置类,根据问题做了改造
继续来看部分配置类,所有涉及到项目信息相关内容都已替换
@Configuration
@MapperScan(valud = "com.test.test.test.impaladao", sqlSessionFactoryRef = "ImpalaSessionFactory")
public class ImpalaDatabaseSource {
@Value("${spring.datasource.druid.impala.url}")
private String url;
@Value("${spring.datasource.druid.impala.driver-class-name}")
private String driverClass;
@Value("${spring.datasource.druid.impala.username}")
private String username;
@Value("${spring.datasource.druid.impala.password}")
private String password;
@Value("${spring.datasource.druid.maxActive}")
private Integer maxActive;
@Value("${spring.datasource.druid.initial-size}")
private Integer initialSize;
@Value("${spring.datasource.druid.min-idle}")
private Integer minIdle;
@Value("${spring.datasource.druid.maxWait}")
private Integer maxWait;
@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
private Long timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
private Long minEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.druid.testWhileIdle}")
private Boolean testWhileIdle;
@Value("${spring.datasource.druid.testOnBorrow}")
private Boolean testOnBorrow;
@Value("${spring.datasource.druid.testOnReturn}")
private Boolean testOnReturn;
@Value("${mybatis.typeAliasesPackage}")
private String aliasesPackage;
@Value("${mybatis.mapper-locations}")
private String locations;
@Bean(name="impalaDataSource")
public DataSource impalaDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setMaxActive(maxActive);
dataSource.setInitialSize(initialSize);
dataSource.setMinIdle(minIdle);
dataSource.setMaxWait(maxWait);
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
dataSource.setValidationQuery(validationQuery);
dataSource.setTestWhileIdle(testWhileIdle);
dataSource.setTestOnBorrow(testOnBorrow);
dataSource.setTestOnReturn(testOnReturn);
return dataSource;
}
}
这边可以看到我把配置文件中的几个检测连接的重要属性都放到了配置类中,这样就可以识别了
不过需要注意的是validationQuery 这个参数我给的值是select 1 ,这是为了适配impala,oracle不一定能够识别,如果两个数据源都要用的小伙伴建议单独写
做完这些后把项目重新发布一下就能够正常使用了
|