数据连接池默认配置带来的坑testOnBorrow=false,cloes_wait 终于解决了

2023-11-16

转载地址:http://blog.csdn.net/soberchina/article/details/72953996


首先说一下自己程序中遇到的问题,前一段新写了一个项目,主要为方便公司业务切库做准备,为其他项目提供接口(spring boot 项目<spring boot + mongo data jpa+mybatis>) 首先呢 多数据源没有使用spring boot 集成mybatis,开始有过自己搭建spring boot 都是单数据源的,所以没有自己手写加载数据源的代码(比较懒),在新项目中使用的是阿里的druid连接池,配置当然更简单了,除了数据库地址,驱动类,用户名和密码其他一起都是默认,开始的时候由于项目更新上线频率比较多,没有出现太多的问题,而且访问比较频繁,接着慢慢提供接口,后来上线了一个 访问频率不大的接口,那么问题就出现了,隔了一段时间,某一台服务器挂了,服务器 netstat -ant | wc -l  六七千,netstat -ant | tail  链接出现大量的close_wait ,很是头疼,开始从tcp下手找问题,这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。


看了一下不会出现中途死掉的问题,作为服务端关闭处理应该在tomcat上,spring Boot 内嵌的tomcat不可能这么弱,后来查了一下dump 发现线程卡在

sun.misc.Unsafe.park(Unsafe.java:-2) native
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:1521) 
com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1146)

 这时候开始考虑数据库连接池的问题 ,跟了一下代码以及其他项目的配置,其中有一个属性 testOnBorrow设置为false(默认设置为false) testOnBorrow=false由于不检测池里连接的可用性,

于是假如连接池中的连接被数据库关闭了,应用通过连接池getConnection时,都可能获取到这些不可

用的连接,且这些连接如果不被其他线程回收的话,它们不会被连接池被废除,也不会重新被创建,

占用了连接池的名额,项目本身作为服务端,数据库链接被关闭,客户端调用服务端就会出现大量的timeout,客户端设置了超时时间,然而主动断开,服务端必然出现close_wait。spring Boot 内嵌的tomcat 默认最大线程数是200,很快就挂掉,虽说多数源,没有问题的数据源,链接并发过来也会死掉,所以说加大tomcat 默认线程(server.tomcat.max-threads=3000)只是短时间内其他数据源链接不会死掉,现在对比一下连接池 druid 如图:


spring boot 集成mybatis 默认使用 jdbc连接池

org.apache.tomcat.jdbc.pool默认testOnBorrow=false 



 

但是在 spring boot 集成mybatis时候 却默认修改了配置如图:



 

这篇文章解释的挺不错

http://blog.csdn.net/wangyangzhizhou/article/details/52209336

默认的配置不适用所有场景,需要注意一下。

 但是这个锅不能丢给druid,testOnborrow =true 很大的消耗性能,从而保证服务器的稳定,可以配合其他配置来避免这一点,配合testWhileIdle=true(但是默认为false) 和timeBetweenEvictionRunsMillis来避免这种问题,这么重要的几个配置,为什么都要默认为false呢,为了提高效率,从而导致服务器很大的潜在问题?自认为有点儿得不偿失,(最起码默认一种折中的配置感觉比较好)。

下面的注释为转来的。很详细

 

 

 

tomcatde DHCP的配置

<Resource driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" 

logAbandoned="true" maxActive="20" maxIdle="2" maxWait="5000" name="system" 

removeAbandonedTimeout="60" removeAbandoned="true" 

password="xx" type="javax.sql.DataSource"

url="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=base" 

username="sa"/>

当中的

logAbandoned="true"  removeAbandoned="true" removeAbandonedTimeout="60"

就是用来配置数据库断开后自动连接的。

 

 

数据库连接池会在启动时就建立所需的若干连接,并一直保持连接状态,

但是当数据库服务停止后,这些连接就被外部因素给中断了

网上优化了的配置信息:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  

<property name="driverClassName" value="${db.driverClassName}"/>  

<property name="url" value="${db.url}"/>  

<property name="username" value="${db.username}"/>  

<property name="password" value="${db.password}"/>  

<!--initialSize: 初始化连接-->  

<property name="initialSize" value="5"/>  

<!--maxIdle: 最大空闲连接-->  

<property name="maxIdle" value="10"/>  

<!--minIdle: 最小空闲连接-->  

<property name="minIdle" value="5"/>  

<!--maxActive: 最大连接数量-->  

<property name="maxActive" value="15"/>  

<!--removeAbandoned: 是否自动回收超时连接-->  

<property name="removeAbandoned" value="true"/>  

<!--removeAbandonedTimeout: 超时时间(以秒数为单位)-->  

<property name="removeAbandonedTimeout" value="180"/>  

<!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒-->  

<property name="maxWait" value="3000"/>  

<property name="validationQuery">  

<value>SELECT 1</value>  

</property>  

<property name="testOnBorrow">  

<value>true</value>  

</property>  

</bean>  

 

dbcp配置中文版本,自apache 官方文档

原文请见http://commons.apache.org/dbcp/configuration.html。

 

参数  描述

username  传递给JDBC驱动的用于建立连接的用户名

password  传递给JDBC驱动的用于建立连接的密码

url  传递给JDBC驱动的用于建立连接的URL

driverClassName  使用的JDBC驱动的完整有效的java 类名

connectionProperties  当建立新连接时被发送给JDBC驱动的连接参数,

格式必须是 [propertyName=property;]*

注意 :参数user/password将被明确传递,所以不需要包括在这里。

 

参数  默认值  描述

defaultAutoCommit  true  连接池创建的连接的默认的auto-commit状态

defaultReadOnly  driver default  连接池创建的连接的默认的read-only状态. 

如果没有设置则setReadOnly方法将不会被调用. (某些驱动不支持只读模式,比如:Informix)

defaultTransactionIsolation  driver default  连接池创建的连接的默认的TransactionIsolation状态. 

下面列表当中的某一个: (参考javadoc)

 

    * NONE

    * READ_COMMITTED

    * READ_UNCOMMITTED

    * REPEATABLE_READ

    * SERIALIZABLE

 

defaultCatalog   连接池创建的连接的默认的catalog

 

参数  默认值  描述

initialSize  0  初始化连接:连接池启动时创建的初始化连接数量,1.2版本后支持

maxActive  8  最大活动连接:连接池在同一时间能够分配的最大活动连接的数量, 

如果设置为非正数则表示不限制

maxIdle  8  最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,

如果设置为负数表示不限制

minIdle  0  最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,

如果设置为0则不创建

maxWait  无限  最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),

超过时间则抛出异常,如果设置为-1表示无限等待

 

参数  默认值  描述

validationQuery   SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,

则查询必须是一个SQL SELECT并且必须返回至少一行记录

testOnBorrow  true  指明是否在从池中取出连接前进行检验,如果检验失败,

则从池中去除连接并尝试取出另一个.

注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

testOnReturn  false  指明是否在归还到池中前进行检验

注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

testWhileIdle  false  指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,

则连接将被从池中去除.

注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

timeBetweenEvictionRunsMillis  -1  在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位.

 如果设置为非正数,则不运行空闲连接回收器线程

numTestsPerEvictionRun  3  在每次空闲连接回收器线程(如果有)运行时检查的连接数量

minEvictableIdleTimeMillis  1000 * 60 * 30  连接在池中保持空闲而不被空闲连接回收器线程

(如果有)回收的最小时间值,单位毫秒

 

参数  默认值  描述

poolPreparedStatements  false  开启池的prepared statement 池功能

maxOpenPreparedStatements  不限制  statement池能够同时分配的打开的statements的最大数量, 

如果设置为0表示不限制

 

 

这里可以开启PreparedStatements池. 当开启时, 将为每个连接创建一个statement池,

并且被下面方法创建的PreparedStatements将被缓存起来:

    * public PreparedStatement prepareStatement(String sql)

    * public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

注意: 确认连接还有剩余资源可以留给其他statement

参数  默认值  描述

accessToUnderlyingConnectionAllowed  false  控制PoolGuard是否容许获取底层连接

 

 

如果容许则可以使用下面的方式来获取底层连接:

    Connection conn = ds.getConnection();

    Connection dconn = ((DelegatingConnection) conn).getInnermostDelegate();

    ...

    conn.close();

 

默认false不开启, 这是一个有潜在危险的功能, 不适当的编码会造成伤害.

(关闭底层连接或者在守护连接已经关闭的情况下继续使用它).请谨慎使用,

并且仅当需要直接访问驱动的特定功能时使用.

注意: 不要关闭底层连接, 只能关闭前面的那个.

参数  默认值  描述

removeAbandoned  false  标记是否删除泄露的连接,如果他们超过了removeAbandonedTimout的限制.

如果设置为true, 连接被认为是被泄露并且可以被删除,如果空闲时间超过removeAbandonedTimeout. 

设置为true可以为写法糟糕的没有关闭连接的程序修复数据库连接.

removeAbandonedTimeout  300  泄露的连接可以被删除的超时值, 单位秒

logAbandoned  false  标记当Statement或连接被泄露时是否打印程序的stack traces日志。

被泄露的Statements和连接的日志添加在每个连接打开或者生成新的Statement,

因为需要生成stack trace。

 

 

如果开启"removeAbandoned",那么连接在被认为泄露时可能被池回收. 这个机制在(getNumIdle() < 2)

 and (getNumActive() > getMaxActive() - 3)时被触发.

举例当maxActive=20, 活动连接为18,空闲连接为1时可以触发"removeAbandoned".

但是活动连接只有在没有被使用的时间超过"removeAbandonedTimeout"时才被删除,默认300秒.

在resultset中游历不被计算为被使用.

  • 大小: 51.7 KB
  • 大小: 248.2 KB
  • 大小: 109.5 KB
  • 大小: 123.8 KB

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据连接池默认配置带来的坑testOnBorrow=false,cloes_wait 终于解决了 的相关文章

  • 【Web server failed to start. Port 8080 was already in use】解决方案

    问题描述 你是否遇到过这个问题呢 无论是初学者 还是中高级开发者 你都会遇到这个问题 我们就来总结一下 Web server failed to start Port 8080 was already in use Description
  • 刷脸支付俨然形成风口抓住风口才能起飞

    刷脸支付项项目的热度越来越高 更多的支付巨头参与到其中来 最近各大银行联合发布了刷脸支付刷脸付 把刷脸支付的热度推到一个新的高度 刷脸支付这么火热 各大支付巨头纷纷投入巨额资金抢占市场 随着我国支付行业的发展 刷脸支付已然成为下一代支付方式

随机推荐

  • 恶劣天气 3D 目标检测数据集收集

    Summary of the Adverse Weather 3D Object Detection Dataset DENSE数据集 CADC数据集 Ithaca365数据集 DENSE数据集 论文地址 https arxiv org p
  • 设备树(dtb数据)匹配struct machine_desc结构体

    1 函数调用关系 start kernel setup arch setup machine fdt 解析dtb数据 得到匹配的struct machine desc结构体 这是用来描述板级配置的 early init dt verify
  • Socket连接和Http连接

    Socket连接与HTTP连接 我们在传输数据时 可以只使用 传输层 TCP IP协议 但是那样的话 如果没有应用层 便无法识别数据内容 如果想要使传输的数据有意义 则必须使用到应用层协议 应用层协议有很多 比如HTTP FTP TELNE
  • 分数的拆分原理和方法_四年级数学计算方法和技巧汇总,附口算练习,赶紧给孩子看!...

    简便运算的方法 1 提取公因式 这个方法实际上是运用了乘法分配律 将相同因数提取出来 考试中往往剩下的项相加减 会出现一个整数 注意相同因数的提取 例如 0 92 1 41 0 92 8 59 0 92 1 41 8 59 2 借来借去法
  • java框架之ssh框架之认识

    SSH框架 1 SSH框架是什么 SSH框架是struts spring hibernate的一个集成框架 分为四层 表示层 业务逻辑层 数据持久层和域模块层 其中使用Struts作为系统的整体基础架构 负责MVC的分离 在Struts框架
  • 【实例分割】5、Look Closer to Segment Better

    文章目录 一 背景 二 动机 三 方法 3 1 Boundary Patch Extraction 3 2 Boundary Patch Refinement 3 3 Learning and Inference 四 实验 Paper ht
  • python语法-pyspark实战(数据输出)

    将RDD对象转化为python对象 1 collect算子 collect算子 功能 将RDD各个分区内的数据 统一收集到Driver中 形成一个list对象 用法 rdd collect 返回值是一个list 2 reduce算子 col
  • Jmeter实现登录不同的账号,去完成不同版本的业务流程

    一 思路 通过线程数量去控制你想要登录的用户数量 登录后获取可以区分不同业务流程的字段值 使用循环控制器 在循环控制器下添加if控制器从而去执行不同版本的业务流程 二 简单介绍一下思路中提到插件配置 线程组 方式一 方式二 2 获取登录后的
  • 百元买百鸡4

    题目 公鸡5元钱一只 母鸡3元钱一只 小鸡3只一元钱 用100元钱买一百只鸡 其中公鸡 母鸡 小鸡都必须要有 问公鸡 母鸡 小鸡要买多少只刚好凑足100元钱 思路 公鸡 母鸡 小鸡 100 5 公鸡 3 母鸡 小鸡 3 100 需要两个条件
  • 基于Java平台实现发送短信功能

    首先我们需要一个平台来帮助我们发送短信 而我们是调用它的接口 使用中国网建的SMS平台相对简单 因此需要去平台 https www smschinese com cn reg shtml 注册 1 跳转到注册页面并填写信息 2 注册后点击登
  • 申请软著详细流程

    相信有很多小白和本人一样不知道如何自己申请软著 只要耐心按照读完此文 保证自己可以独立申请啦 如果自己申请的话 目前软著登记是免费的 自己也就付个邮费 如果是加急的话 可以找三方代理机构办理 反正时间越短 价格越高 正常自己申请的话 最后拿
  • jQuery学习

    1 引入jqueryDownload jQuery jQuery 2 是jQuery的别称 以下两种等效 function div hide jQuery function jQuery div hide 3 jQuery对象和DOM对象
  • 线索二叉树(中序、先序和后序及遍历)

    链式存储 线索二叉树是二叉树的一类 在看线索二叉树之前我们先看一下二叉树的链式存储 一个二叉树的存储例子 后面用到的二叉树都是这棵 代码是这样的 public class BinaryTreeNode
  • 看看Docker Desktop WSL2 backend

    一 前言 这篇文章将通过 Docker Desktop 最新版以 WSL2 作后端 VirtualBox 和 VMware 最新版能和 Hype V 共存 等方面来表达笔者对微软重新认识 实际上笔者对 Docker 的使用也没多长时间 而且
  • 【包真】我的第一次webpack优化,首屏渲染从9s到1s

    大家好 我是猫小白 本文基于vue2 全文阅读大约需要3分钟 谈到webpack优化大部分人可能都看腻了 无非就那几招嘛 我之前也是看过许多类似的文章 但都没有自己真正上手过 下面是我用公司的项目真实操练下来的 首屏加载速度提升很大 刷刷的
  • tf-idf+lda分析多篇文章摘要

    import pandas as pd import numpy as np import matplotlib pyplot as plt import seaborn as sns plt rcParams font sans seri
  • 最常见的8个Android内存泄漏问题及解决方法

    作者 午后一小憩 在 Android 开发中 内存泄漏是一个常见的问题 这个问题可能会导致应用程序变慢 崩溃或者消耗大量的内存 最终导致设备性能下降 什么是内存泄漏 内存泄漏指的是应用程序中存在一些对象或者资源无法被垃圾回收器回收 导致内存
  • Linux获取文件属性

    以 rw rw r 1 ubuntu ubuntu 56 八月 1 19 37 1 txt 为例 一 stat函数 功能 获取文件的属性 函数原型 include
  • 根据数据生成地图并着色

    前言 我们有时会拿到一些数据与国家或者地区密切相关 故在地图上将其可视化会更为直观 同时也会提高数据分析的效率 利用Map绘制地图 以世界地图为例 数据形式如下 表中数据是我乱编的 一 导入必要的库 import pandas as pd
  • 数据连接池默认配置带来的坑testOnBorrow=false,cloes_wait 终于解决了

    转载地址 http blog csdn net soberchina article details 72953996 首先说一下自己程序中遇到的问题 前一段新写了一个项目 主要为方便公司业务切库做准备 为其他项目提供接口 spring b