spring boot 项目中数据库连接池的配置问题研究

重要:SpringBoot 2.0 开始推 HikariCP ,将默认的数据库连接池从 tomcat jdbc pool 改为了 hikari , HikariCP 在性能和并发方面确实表现不俗(号称最快的连接池)。

一、当我们遇到这个问题该怎么办?用户“***”连接超过了最大资源数。

考虑修改数据库连接池的默认设置或者不使用数据库连接池技术;

二、什么是数据库连接池技术?

数据库连接池是不需要用户申请和释放数据库的连接,他会自动帮您管理数据库的连接用户只管使用这个连接,连接池会自动释放已经用过的连接,当连接不够用的时候他会自动申请新的连接,这样循环周而复始,保证数据库连接的可用性。大家可以理解为连接池是自动帮助用户管理数据库的连接的地方,这样就不会发生上面的数据库连接忘记关闭的问题

  数据库连接池会在tomcat启动的时候就自动申请好数据库连接(申请多少数据库连接根据您的配置文件里设置的决定的),放在一个虚拟的池子里面,您调用数据库的时候从这个池子里拿,用完了池子会自动回收你已经用过的这个连接,为下一个连接做准备!

  使用了数据库连接池,连接池会有一个配置文件,配置文件里可以规定他在启动的时候申请最大多少个连接,最小多少个连接,初始多少个连接,一个连接可以存活多久等。

三、为什么要使用数据库连接池技术?

1、数据库并发,数据库同时可以被多个人操作,或者多个客户端请求连接数据库;

2、部分用户申请完数据库连接后,忘记关闭这个数据库连接(这样的问题由于程序员的大意也是时有发生的);

这时候就需要一个中间件管理连接,协助用户进行申请和释放数据库的链接。事先创建好数据库连接放在“数据库连接池”中等你来用,用完了就释放,这样就避免了每次请求连接数据库都要创建连接,节省资源,缩短反应时间。数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。


使用数据库连接池技术的示意图

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.

  数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:

最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.

最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作

如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.

四、如何设置连接池

根据自己程序的并发个数;

以20个并发为例子 连接池我们建议设置

最大连接为:19

最小连接为:5

初始连接为:5

过期时间为:120秒

如果并发是30个的话只需要把上面的最大连接数设置为29个即可,其他的不变。如果把最小连接数和初始连接数设置过大,则会影响数据库连接池的性能。

可以参考:http://www.jspkongjian.net/news.jsp?id=790

五、spring boot项目的连接池技术研究

创建Spring boot 项目使用spring-boot-starter-data-jpa,POM下载的依赖包里会包含spring-boot-starter-jdbc的依赖包,该依赖包绑定com.zaxxer:HikariCP.


控制台获取信息


找到相应的jar包

看看这里的默认配置

找到直接使用的配置文件源码来看看,如下:


HikariDataSource源码

HikariDataSource继承HikariConfig实现了接口DataSource, Closeable两个接口。

再来看看HikariConfig的源码:


默认配置都在这里

简书不合适贴代码,但还是贴出来,免得大家再去找:

public class HikariConfigimplements HikariConfigMXBean

{

private static final LoggerLOGGER = LoggerFactory.getLogger(HikariConfig.class);

private static final char[]ID_CHARACTERS ="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

private static final long CONNECTION_TIMEOUT =SECONDS.toMillis(30);

private static final long VALIDATION_TIMEOUT =SECONDS.toMillis(5);

private static final long IDLE_TIMEOUT =MINUTES.toMillis(10);

private static final long MAX_LIFETIME =MINUTES.toMillis(30);

private static final int DEFAULT_POOL_SIZE =10;

private static boolean unitTest =false;

// Properties changeable at runtime through the HikariConfigMXBean

//

  private volatile long connectionTimeout;

private volatile long validationTimeout;

private volatile long idleTimeout;

private volatile long leakDetectionThreshold;

private volatile long maxLifetime;

private volatile int maxPoolSize;

private volatile int minIdle;

private volatile Stringusername;

private volatile Stringpassword;

// Properties NOT changeable at runtime

//

  private long initializationFailTimeout;

private Stringcatalog;

private StringconnectionInitSql;

private StringconnectionTestQuery;

private StringdataSourceClassName;

private StringdataSourceJndiName;

private StringdriverClassName;

private StringjdbcUrl;

private StringpoolName;

private Stringschema;

private StringtransactionIsolationName;

private boolean isAutoCommit;

private boolean isReadOnly;

private boolean isIsolateInternalQueries;

private boolean isRegisterMbeans;

private boolean isAllowPoolSuspension;

private DataSourcedataSource;

private PropertiesdataSourceProperties;

private ThreadFactorythreadFactory;

private ScheduledExecutorServicescheduledExecutor;

private MetricsTrackerFactorymetricsTrackerFactory;

private ObjectmetricRegistry;

private ObjecthealthCheckRegistry;

private PropertieshealthCheckProperties;

private volatile boolean sealed;

/**

* Default constructor

*/

  public HikariConfig()

{

dataSourceProperties =new Properties();

healthCheckProperties =new Properties();

minIdle = -1;

maxPoolSize = -1;

maxLifetime =MAX_LIFETIME;

connectionTimeout =CONNECTION_TIMEOUT;

validationTimeout =VALIDATION_TIMEOUT;

idleTimeout =IDLE_TIMEOUT;

initializationFailTimeout =1;

isAutoCommit =true;

String systemProp = System.getProperty("hikaricp.configurationFile");

if (systemProp !=null) {

loadProperties(systemProp);

}

}

仔细看一下,发现初始化配置有3种方式:

第一种:Default constructor

假如我们不写自己的配置时,就使用这个构造器中的默认参数初始化;

minIdle = -1;

maxPoolSize = -1;

maxLifetime =MAX_LIFETIME;  //30s

connectionTimeout =CONNECTION_TIMEOUT;  //30s

validationTimeout =VALIDATION_TIMEOUT;    // 5s

idleTimeout =IDLE_TIMEOUT;  // 10s

initializationFailTimeout =1;

isAutoCommit =true;

默认的连接池的大小是10;

final int DEFAULT_POOL_SIZE =10;


第二种:大概就是根据我们在spring boot 项目中的 properties.yml文件中设置的属性

/**

* Construct a HikariConfig from the specified properties object.

*

* @param properties the name of the property file

*/

第三种:根据file类型的配置文件

/**

* Construct a HikariConfig from the specified property file name.  <code>propertyFileName</code>* will first be treated as a path in the file-system, and if that fails the

* Class.getResourceAsStream(propertyFileName) will be tried.

*

* @param propertyFileName the name of the property file

*/

有个大哥总结了一下:https://blog.csdn.net/MyHerux/article/details/80730690

阿里的数据库连接池技术研究:https://www.cnblogs.com/wuyun-blog/p/5679073.html

研究这一问题的起因:


局部


全局

2018-12-05 16:39:12.566 ERROR 5712 --- [          main] o.h.engine.jdbc.spi.SqlExceptionHelper  : User 'root' has exceeded the 'max_connections_per_hour' resource (current value: 100)

root用户每一个小时连接资源的次数超过了100次,连接被拒绝!

怎么办,难道我在这里坐着等一个小时以后再调试,显然不可以,不能打着技术“瓶颈”的幌子“磨洋工”。于是,我试着解决这一报错。

最简单的解决办法:


停止MySQL Server,重启

,转了一圈发现根本不是我改配置能解决的,用这招轻松解决。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 11,232评论 4 56
  • 2005年4月份,我本想靠一个羊屎蛋换毕业证书,但是事与愿违,经历过那么多的波折,我即将上大学八年级。这句话的意思...
    国产大青蛙阅读 516评论 0 0
  • 今年一月,我收到了小学同学结婚的消息,她让我们几个玩的最好的朋友一起去做伴娘,就在明天,她就要出嫁了。 以前我就说...
    苏溪阅读 481评论 0 1
  • 刷朋友圈对我是个很严峻的考验,你知道的,像我这样一个大好青年,朋友圈也净是些大好青年,外加大好娃娃。晒娃党孜孜不倦...
    微冷微冷阅读 35,497评论 29 43