记录一下生产环境遇到的问题
生产上的一个程序跑了一段时间后,老是出现 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 # 监测空闲连接的时间间隔

解决办法

复现了问题,来记录下解决办法

  1. 调整oracle数据库的超时连接配置,配置为无限制

    1. oracle数据库修改用户profiles的idle_time mysql数据库修改数据库配置 wait_time
  2. 修改druid连接池配置
    1. 调低 timeBetweenEvictionRunsMillis 扫描间隔, 这意味着druid会更频繁的扫描连接池中的无效连接
    2. 调低 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连接超时关闭问题相关推荐

  1. oracle连接超时 时好时坏,关于Oracle连接超时的问题

    测试环境ORACLE 11.2.0. 如果连接池设置单个连接闲置时间大于数据库连接超时时间,则连接池中的连接发出数据请求时会出现Connect timeout occurred错误, 这是由于连接超时 ...

  2. 如何解决MySQL连接超时关闭

    最近做网站有一个站要用到WEB网页采集器功能,当一个PHP脚本在请求URL的时候,可能这个被请求的网页非常慢慢,超过了mysql的 wait-timeout时间,然后当网页内容被抓回来后,准备插入到M ...

  3. MySQL连接问题【如何解决MySQL连接超时关闭】

    --MySQL连接问题[如何解决MySQL连接超时关闭] ------------------------------------------------转载 最近做网站有一个站要用到WEB网页采集器 ...

  4. 解决Oracle连接超时的方案(菜鸟简述)

    因为近期的项目用到了Oracle数据库,所以自己就学着安装了一下,属于菜鸟级别经常遇到的问题,大神可以自觉离开.. 1.开始的时候在项目中启动项目,报错,显示连接Oracle数据库出错,于是用客户端尝 ...

  5. oracle连接超时是什么意思,oracle数据库连接超时怎么办 求指导oracle远程连接超时怎么办...

    今天给大家带来oracle数据库连接超时怎么办,求指导oracle远程连接超时怎么办,让您轻松解决问题.       oracle数据库是开发人员必备的一个数据库,但是有些小伙伴们,经常会出现这样的问 ...

  6. Druid获取连接超时,导致服务不可用

    前言 一个微服务模块在运行一段时间之后,整体服务就不可用了,但是服务却没有打印任何错误日志.而对服务进行重启之后,服务就可以暂时提供一段时间服务,过一段时间之后再次不可用. 分析 服务进行重启就可以正 ...

  7. .net oracle 连接超时_ADO.NET (一) 前言

    ADO.NET     (一) 前言 前导课程: SQL 数据库 C#程序基础 WPF 界面开发技术 WinForm 界面开发 一.ADO.NET介绍 1. 什么是ADO.NET ADO ( Acti ...

  8. oracle连接超时是什么意思,oracle连接超时自动断开问题

    今天接到客户电话,描述新建的oracle 11.1.0.7 RAC数据库中,当一个用户连接到数据库上以后,如果在某一段时间内没有任何动作的话,该进程就会自己中断,这样在应用程 序就会因为进程超时自动断 ...

  9. java 关闭oracle连接_Java应用中Oracle连接不关闭

    在一些不使用连接池的较老的Java Web应用程序中,我有一个连接泄漏. 查找泄漏很困难,因为它不会授予我访问v$session的权限 SELECT Count(*) FROM v$session; ...

最新文章

  1. ISA2006标准版配置导入企业版
  2. Rational Rose2007无法启动,提示缺少“suite objects.dll”
  3. 高德地图 街道范围_高德地图发布交通“评诊治”系统:针对各类交通拥堵场景“因地制宜”...
  4. 世界杯,世界共同的游戏!
  5. 还不会docker+k8s?2020年,就要面对现实了...
  6. app inventor HTML5,[App Inventor] Web客戶端元件 POST 傳值的使用方式
  7. html诗词赏析网页制作步骤,制作网页详细操作步骤
  8. 判断用户输入的银行卡号是否正确--基于Luhn算法的格式校验
  9. 【C++】智能指针(auto_ptr,shared_ptr,unique_ptr)及 shared_ptr 强引用原理
  10. 基于表格存储的高性能监控数据存储计算方案
  11. java 反射 接口工具类_Java 反射工具类 ReflectionUtils
  12. resize view from nib引起的子控制器视图(childviewcontroller)部分区域无响应
  13. 中铁总数据中心落户武清 项目总投资22.7亿元
  14. golang ide 环境搭建_新手引导 — Golang后端开发环境搭建
  15. 杜比服务器系统安装教程,win10杜比音效如何安装?win10安装杜比音效的详细教程...
  16. Quartz 定时任务
  17. nordic 52832 键盘
  18. ps 学习布尔运算运用方法
  19. [python-opencv]滑动验证码打码
  20. ipa-server

热门文章

  1. 继客户5亿欧元的SAP项目黄了之后,价值1亿欧元的项目SAP又实施失败了!
  2. webpack devtool详解
  3. 前端 Vue 请求数据使用 3DES 加密/解密
  4. 总结:Hive性能优化上的一些总结
  5. Python selenium页面加载缓慢,超时解决办法
  6. Oracle授权详细解释
  7. 【金融】券商研究所策略组的市场行情判断和行业配置有效吗——基于几组回测的结果证明(大大地有效!!)
  8. UWPWP8.1 重新绘制图片 WriteableBitmap用法 图片转byte[]数组,byte[]数组转图片
  9. Git、GitHub搭建及使用
  10. Nginx安装以及基本配置