Druid+Oracle连接超时关闭问题
记录一下生产环境遇到的问题
生产上的一个程序跑了一段时间后,老是出现 Closed Connection异常,往上追溯错误,发现有关闭连接失败异常
该应用环境:
Oracle + Druid + Spirngboot 2.2.9.RELEASE
先搭建本地环境还原报错
环境搭建
引入依赖
主要是druid oracle springboot依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>demo1</artifactId><version>0.0.1-SNAPSHOT</version><name>demo1</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><spring.boot-version>2.2.9.RELEASE</spring.boot-version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring.boot-version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><dependency><groupId>com.oracle</groupId><artifactId>ojdbc6</artifactId><version>11.2.0.3</version></dependency><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>2.1.5</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
配置文件
#spring:
# profiles:
# active: testspring:datasource:driver-class-name: oracle.jdbc.OracleDriverusername: testpassword: testurl: jdbc:oracle:thin:@192.168.164.110:1521:helowintype: com.alibaba.druid.pool.DruidDataSourcedruid:initial-size: 10max-active: 10validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsebreakAfterAcquireFailure: truetimeBetweenConnectErrorMillis: 30000min-evictable-idle-time-millis: 30000 # 超过此时间关闭 除去最小空闲连接之外超过此时间的空闲连接max-evictable-idle-time-millis: 50000 # 超过此时间关闭 除去所有的空闲连接timeBetweenEvictionRunsMillis: 180000 # 监测空闲连接的时间间隔min-idle: 4
模拟程序
使用mybatis开发一个定时1s查询一次数据库的程序即可
package com.example.demo.controller;import com.example.demo.domain.User;
import com.example.demo.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @Author: Zy* @Date: 2021/11/26 14:55*/
@RestController
@Slf4j
public class TimerTestController {@AutowiredUserMapper userMapper;@Scheduled(cron = "*/1 * * * * ?")public void test() {User user = new User();user.setUserName("test");List<User> select = userMapper.select(user);log.info(select.toString());}
}
测试
猜想
测试前先对报错原因进行猜想,首先从生产环境的报错位置:
#com.alibaba.druid.util.JdbcUtils$close(Connection x)方法
public static void close(Connection x) {if (x != null) {try {x.close();} catch (Exception var2) {LOG.debug("close connection error", var2);}}}
此方法调用时机为关闭druid连接池种的连接时调用,此方法内部再调用Connection.Close方法关闭数据库连接
那么猜想出现此报错的原因是调用Connection.close方法时该数据库连接已关闭,是否是因为已关闭的连接再次调用Close方法导致的问题?
测试
启动应用程序
观察日志,确认每次都查询正常
数据库
查看数据库连接数,发现与服务启动时初始化的druid连接数一致.
select sid, username, paddr, status,program,serial# from v$session t where username = 'TEST' and status = 'INACTIVE'
杀死数据库连接
为了验证猜想,我们模拟数据库关闭连接,即直接杀掉jdbc连接
-- 生成杀session报文
select replace(wm_concat('alter system kill session '''||sid||','||serial#||''';'),',','') from v$session where username = 'TEST' and status = 'INACTIVE' and program = 'JDBC Thin Client'-- 执行杀死开启的数据库连接
观察应用日志
总结
经过分析,可以得出结论,出现该异常的原因是:
连接池中初始化了大量的空闲连接,这些连接在一段时间后,超过了数据库的连接超时时间,此时数据库就会单方面关闭这些连接,但是应用中连接池中的连接并没有关闭,等到有新的请求到达,从连接池中获取连接时,该连接其实已经被数据库关闭,此时就会出现该错误
或者,druid每隔一段时间,就会对连接池中的连接进行有效性检查,如果该连接超过了配置的空闲连接时间,就会调用JdbcUtils.close()方法,但是该连接已经被数据库关闭了,此时就会报错 closed connection
跟此次问题相关的druid连接池配置详解
min-evictable-idle-time-millis: 30000 # 超过此时间关闭 除去最小空闲连接之外超过此时间的空闲连接
max-evictable-idle-time-millis: 50000 # 超过此时间关闭 除去所有的空闲连接
timeBetweenEvictionRunsMillis: 180000 # 监测空闲连接的时间间隔
解决办法
复现了问题,来记录下解决办法
- 调整oracle数据库的超时连接配置,配置为无限制
- oracle数据库修改用户profiles的idle_time mysql数据库修改数据库配置 wait_time
- 修改druid连接池配置
- 调低 timeBetweenEvictionRunsMillis 扫描间隔, 这意味着druid会更频繁的扫描连接池中的无效连接
- 调低 min-evictable-idle-time-millis/max-evictable-idle-time-millis 这意味着连接池中的空闲连接在更短的时间内就会被关闭
建议采取第二种方式,原则如下:
timeBetweenEvictionRunsMillis + min-evictable-idle-time-millis < 数据库连接超时时间
max-evictable-idle-time-millis 可以配置的跟 min-evictable-idle-time-millis 一致
Druid+Oracle连接超时关闭问题相关推荐
- oracle连接超时 时好时坏,关于Oracle连接超时的问题
测试环境ORACLE 11.2.0. 如果连接池设置单个连接闲置时间大于数据库连接超时时间,则连接池中的连接发出数据请求时会出现Connect timeout occurred错误, 这是由于连接超时 ...
- 如何解决MySQL连接超时关闭
最近做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到M ...
- MySQL连接问题【如何解决MySQL连接超时关闭】
--MySQL连接问题[如何解决MySQL连接超时关闭] ------------------------------------------------转载 最近做网站有一个站要用到WEB网页采集器 ...
- 解决Oracle连接超时的方案(菜鸟简述)
因为近期的项目用到了Oracle数据库,所以自己就学着安装了一下,属于菜鸟级别经常遇到的问题,大神可以自觉离开.. 1.开始的时候在项目中启动项目,报错,显示连接Oracle数据库出错,于是用客户端尝 ...
- oracle连接超时是什么意思,oracle数据库连接超时怎么办 求指导oracle远程连接超时怎么办...
今天给大家带来oracle数据库连接超时怎么办,求指导oracle远程连接超时怎么办,让您轻松解决问题. oracle数据库是开发人员必备的一个数据库,但是有些小伙伴们,经常会出现这样的问 ...
- Druid获取连接超时,导致服务不可用
前言 一个微服务模块在运行一段时间之后,整体服务就不可用了,但是服务却没有打印任何错误日志.而对服务进行重启之后,服务就可以暂时提供一段时间服务,过一段时间之后再次不可用. 分析 服务进行重启就可以正 ...
- .net oracle 连接超时_ADO.NET (一) 前言
ADO.NET (一) 前言 前导课程: SQL 数据库 C#程序基础 WPF 界面开发技术 WinForm 界面开发 一.ADO.NET介绍 1. 什么是ADO.NET ADO ( Acti ...
- oracle连接超时是什么意思,oracle连接超时自动断开问题
今天接到客户电话,描述新建的oracle 11.1.0.7 RAC数据库中,当一个用户连接到数据库上以后,如果在某一段时间内没有任何动作的话,该进程就会自己中断,这样在应用程 序就会因为进程超时自动断 ...
- java 关闭oracle连接_Java应用中Oracle连接不关闭
在一些不使用连接池的较老的Java Web应用程序中,我有一个连接泄漏. 查找泄漏很困难,因为它不会授予我访问v$session的权限 SELECT Count(*) FROM v$session; ...
最新文章
- ISA2006标准版配置导入企业版
- Rational Rose2007无法启动,提示缺少“suite objects.dll”
- 高德地图 街道范围_高德地图发布交通“评诊治”系统:针对各类交通拥堵场景“因地制宜”...
- 世界杯,世界共同的游戏!
- 还不会docker+k8s?2020年,就要面对现实了...
- app inventor HTML5,[App Inventor] Web客戶端元件 POST 傳值的使用方式
- html诗词赏析网页制作步骤,制作网页详细操作步骤
- 判断用户输入的银行卡号是否正确--基于Luhn算法的格式校验
- 【C++】智能指针(auto_ptr,shared_ptr,unique_ptr)及 shared_ptr 强引用原理
- 基于表格存储的高性能监控数据存储计算方案
- java 反射 接口工具类_Java 反射工具类 ReflectionUtils
- resize view from nib引起的子控制器视图(childviewcontroller)部分区域无响应
- 中铁总数据中心落户武清 项目总投资22.7亿元
- golang ide 环境搭建_新手引导 — Golang后端开发环境搭建
- 杜比服务器系统安装教程,win10杜比音效如何安装?win10安装杜比音效的详细教程...
- Quartz 定时任务
- nordic 52832 键盘
- ps 学习布尔运算运用方法
- [python-opencv]滑动验证码打码
- ipa-server
热门文章
- 继客户5亿欧元的SAP项目黄了之后,价值1亿欧元的项目SAP又实施失败了!
- webpack devtool详解
- 前端 Vue 请求数据使用 3DES 加密/解密
- 总结:Hive性能优化上的一些总结
- Python selenium页面加载缓慢,超时解决办法
- Oracle授权详细解释
- 【金融】券商研究所策略组的市场行情判断和行业配置有效吗——基于几组回测的结果证明(大大地有效!!)
- UWPWP8.1 重新绘制图片 WriteableBitmap用法 图片转byte[]数组,byte[]数组转图片
- Git、GitHub搭建及使用
- Nginx安装以及基本配置