记录 Atomikos数据源连接超时和耗尽导致的应用灾难

本文介绍了一个关于Spring Boot项目中使用Druid连接池遇到的并发访问异常问题。通过对比原生Druid与Atomikos下DruidXADataSource的表现,分析了连接归还速度差异的原因,并提供了解决方案。

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

问题描述

项目使用的网上的springboot封装的框架。项目初期使用一切正常,随着用户量的增加发现应用的响应速递有所下降。这两天系统开始出现间隙性无法访问。追踪日志发现报错

Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 18, maxActive 200, creating 1, createElapseMillis 120000
	at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1739)
	at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1409)
	at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5059)
	at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
	at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5055)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1387)
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1379)
	at com.alibaba.druid.pool.xa.DruidXADataSource.getXAConnection(DruidXADataSource.java:45)
	at com.atomikos.jdbc.AtomikosXAConnectionFactory.createPooledConnection(AtomikosXAConnectionFactory.java:43)
	... 147 more

发现创建数据连接超时,但是实际连接数并没有到大最大连接数。找了很久发现另外一处错误,AtomikosSQLException:连接数已达到pool的上限,无法再创建新的连接

aused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.atomikos.jdbc.AtomikosSQLException: Failed to grow the connection pool
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
	at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82)
	at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68)
	at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:336)
	at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
	at sun.reflect.GeneratedMethodAccessor99.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
	at com.sun.proxy.TProxy105.query(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
	... 123 more

于是在本地使用jmeter 进行压测50并发发现,本地出现一样的问题。于是在网上找相关的错误信息。找了一堆发现没有什么有用信息。最终在一片文章中找到一样的问题,https://blog.youkuaiyun.com/qq_39002724/article/details/106671114  

当使用原生druid时:活跃连接数在并发操作结束后,很快恢复到最小连接数左右
当使用atomikos时:活跃连接数在并发操作结束后,需要等一段时间才能恢复到最小连接数左右
DruidXADataSource的连接归还速度远小于原生druid,导致并发量大的情况下,由于本来占用连接就多,归还速度又慢,最终出现上述问题。
 

参照对应的解决方法,将oracle连接从原先的DruidXADataSource  替换成oracle原生的后,进行压测发现应用正常。

报错之前的代码:

  /**
     * 数据源创建模板
     */
    private static DataSource createDataSource(String dataSourceName, DruidProperties druidProperties) {
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
        atomikosDataSourceBean.setUniqueResourceName(dataSourceName);
        atomikosDataSourceBean.setMaxPoolSize(100);
        atomikosDataSourceBean.setBorrowConnectionTimeout(60);
        atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
        return atomikosDataSourceBean;
    }

修改之后的代码:

 /**
     * 数据源创建模板
     */
    private static DataSource createOracleDataSource(String dataSourceName, DruidProperties druidProperties){
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setUniqueResourceName(dataSourceName);
        atomikosDataSourceBean.setMaxPoolSize(100);
        atomikosDataSourceBean.setBorrowConnectionTimeout(60);
        atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
        try {
            OracleXADataSource mysqlXADataSource = new OracleXADataSource();
            mysqlXADataSource.setURL(druidProperties.getUrl());
            mysqlXADataSource.setUser(druidProperties.getUsername());
            mysqlXADataSource.setPassword(druidProperties.getPassword());
            atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
        }catch (SQLException e){
            e.printStackTrace();
        }
        return atomikosDataSourceBean;
    }

 

10:33:18.623 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - Loaded jar:file:/D:/maven-res/com/atomikos/transactions/4.0.6/transactions-4.0.6.jar!/transactions-defaults.properties 10:33:18.631 [main] WARN c.a.i.p.i.AssemblerImp - [logWarning,24] - Thanks for using Atomikos! Evaluate http://www.atomikos.com/Main/ExtremeTransactions for advanced features and professional support or register at http://www.atomikos.com/Main/RegisterYourDownload to disable this message and receive FREE tips & advice Thanks for using Atomikos! Evaluate http://www.atomikos.com/Main/ExtremeTransactions for advanced features and professional support or register at http://www.atomikos.com/Main/RegisterYourDownload to disable this message and receive FREE tips & advice 10:33:18.642 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.default_max_wait_time_on_shutdown = 9223372036854775807 10:33:18.643 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.allow_subtransactions = true 10:33:18.643 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.recovery_delay = 10000 10:33:18.644 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.automatic_resource_registration = true 10:33:18.644 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.oltp_max_retries = 5 10:33:18.645 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.client_demarcation = false 10:33:18.646 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.threaded_2pc = false 10:33:18.646 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.serial_jta_transactions = true 10:33:18.647 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.log_base_dir = D:\qz\yjs-202534-server\transaction-logs 10:33:18.647 [main] INFO c.a.i.p.i.AssemblerImp - [logInfo,28] - USING: com.atomikos.icatch.rmi_expor
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值