前言:

最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测机制, 导致sql执行失败.

问题的表层根源, 看似简单, 但实际解决之路, 却显得有些曲折坎坷. 因此有必须分析下本质的原因, 以及Java Mysql连接池的处理策略和相关的配置项.

异常现象和问题本源:

服务的持久层依赖mysql, 采用连接池的机制来优化性能. 但服务空闲一段时间(切确地讲是mysql connection空闲一段时间), 下次使用时执行sql失败.

具体的异常, 可反映到具体的异常日志:

当然除了异常的原因以外, 里面也提供了一个解决方案.

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:

The last packet successfully received from the server was 47,302,202 milliseconds ago.

The last packet sent successfully to the server was 47,302,202 milliseconds ago.

is longer than the server configured value of 'wait_timeout'.

You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts,

or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

暂且不管这个autoReconnect=true的解决方案是否有效, 我们来分析下问题本质.

Mysql进程对拥有的资源, 都有其相应的回收策略. 比如空闲连接, 超过一段时间间隔后, mysql就会主动关闭该连接. 而这个时间间隔就由wait_timeout和interactive_timeout来确定.

Mysql服务器关闭该空闲连接后,而客户端的连接并没有主动去关闭,导致首次使用时,执行失败.

顺便谈谈mysql里面涉及的两个概念: 交互式连接和非交互式连接.

网上争议和吐槽都很多, 但从官网的解读来看, 或许只是mysql_real_connect()调用时, 是否打开CLIENT_INTERACTIVE开关. 再深入的区别解读, 或许已经没有意义了.

交互式连接, 由interactive_timeout来确定, mysql的命令行工具即是该类型.

非交互式连接, 则由wait_timeout来决定, jdbc/odbc等方式的连接即为该类型, 一般而言, Java Mysql连接池属于该类别,需关注wait_timeout项.

曲折的路途:

先后采用两种方式,一种是设置重连选项,另一种是连接池主动淘汰.

• 设置重连选项

按照异常中附带的建议,再jdbc的url中添加了属性autoReconnect=true.

原本以为妥妥的,没想到事与愿违, 还是出现了类似的错误.

参照网上革命战友的说法,mysql5以后autoReconnet=true已经失效了, 具体可以参考Bug #5020.

• 连接池主动淘汰

在配置的连接池中,按一定的规则淘汰掉空闲连接,降低死链被使用的概率.

1). testBeforeUse/testAfterUse

testBeforeUse顾名思义, 就是把连接从连接池中取出时, 先执行validation sql,再执行目标的sql语句. testAfterUse则刚好相反,再放回连接池时进行检测.

虽然每次执行,都会额外的执行一次validation sql,但还是完美的解决上述的问题。不过需要注意的是,其代价昂贵,在高并发情况下需慎用.

2). 定时任务+按空闲阈值淘汰

按一定时间间隔执行清理任务,设定空闲时间的上限,一旦检测到连接其空闲时间超过该阈值,则主动关闭掉. 当然定时周期和空闲阈值都小于wait_timeout值.

3). 定时任务+validation sql检测淘汰

按一定时间间隔执行清理任务,对空闲连接进行validation sql检测, 若失败则主动关闭. 这种方式是testBeforeUse/testAfterUse的有益补充, 有效减少了执行validation sql的次数,解决了代价高昂的窘境. 当然定时周期小于wait_timeout值.

DBCP举例:

我们选用DBCP作为连接池配置的样例, 看看它如何实现上述谈到的主动淘汰策略的.

先来看下DBCP关于空闲连接处理的配置项:

validationQuery

SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录

testOnBorrow

true

指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

testOnReturn

false

指明是否在归还到池中前进行检验注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

testWhileIdle

false

指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串

timeBetweenEvictionRunsMillis

-1

在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程

numTestsPerEvictionRun

3

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

minEvictableIdleTimeMillis

1000 * 60 * 30

连接在池中保持空闲而不被空闲连接回收器线程(如果有)回收的最小时间值,单位毫秒

注:如果想看更多DBCP的配置项, 请参考博文: DBCP的参数配置;

1). testBeforeUse/testAfterUse

destroy-method="close">

2). 定时任务+按空闲阈值淘汰

destroy-method="close">

3). 定时任务+validation sql检测淘汰

destroy-method="close">

事实上,这三种策略除了单独配置,还可以组合,甚至全部启用.

附带:

其实mysql有很多特性, 我们未必真得熟悉.

如何展示mysql的配置变量值:

注:可以看到wait_timeout为28800(28800=60 * 60 * 8), 这就是著名的8小时问题的出处.

如何修改变量:

注:需要注意全局变量和会话变量,以及如何生效.

如何查看mysql的连接数:

总结:

算是一个总结归纳之作, 对于很多革命战友提议说把wait_timeout设长, 我感觉还是治标不治本. 因此就没阐述这个想法, 权当笔记.

公众号&游戏站点:

个人微信公众号: 木目的H5游戏世界

hibernate+mysql的连接池配置

1:连接池的必知概念    首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...

tomcat中使用mysql连接池的配置

1.下载相应的jar包,添加到工程中 需要下载的包主要有commons-pool2-2.2 commons-dbcp2-2.0.1-src commons-dbcp2-2.0.1  commons-c ...

【Mysql】SpringBoot阿里Druid数据源连接池配置

一.pom.xml添加 com.alibaba &l ...

c3p0、dbcp、tomcat jdbc pool 连接池配置简介及常用数据库的driverClass和驱动包

[-] DBCP连接池配置 dbcp jar包 c3p0连接池配置 c3p0 jar包 jdbc-pool连接池配置 jdbc-pool jar包 常用数据库的driverClass和jdbcUrl ...

java自定义连接池

1.java自定义连接池 1.1连接池的概念: 实际开发中"获取连接"或“释放资源”是非常消耗系统资源的两个过程,为了姐姐此类性能问题,通常情况我们采用连接池技术来贡献连接Conn ...

Eclipse+Tomcat7.0+MySQL 连接池设置

http://blog.sina.com.cn/s/blog_85d71fb70101ab99.html 工程名:JavaWeb 第一步:配置server.xml 在Tomcat的server.xml ...

[JavaEE] Hibernate连接池配置测试

转载自51CTO http://developer.51cto.com/art/200906/129914.htm Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以 ...

mysql连接池的使用工具类代码示例

mysql连接池代码工具示例(scala): import java.sql.{Connection,PreparedStatement,ResultSet} import org.apache.co ...

随机推荐

ie浏览器下,get请求缓存问题

1 使用get请求数据 1)Java代码 $.getJSON("sortShow!sortShow?time="+new Date().getTime(),function(){} ...

倒计时的js实现 倒计时 js Jquery

by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=987 一.如火如荼的团 ...

jquery EasyUI的formatter格式化函数代码

要格式化数据表格列,需要设置formatter属性,该属性是一个函数,它包含两个参数:  value: 对应字段的当前列的值  record: 当前行的记录数据  复制代码 代码如下: $('#tt' ...

Java中单例七种写法(懒汉、恶汉、静态内部类、双重检验锁、枚举)

/*** * 懒汉模式 1 * 可以延迟加载,但线程不安全. * @author admin * */ public class TestSinleton1 { private static Test ...

Controller <-> View 一般视图层级

关于 self.navigationController.view 相信看过 MBProgressHUD 官方例子 HudDemo 代码的同学应该看到过下述代码: 1 HUD = [[MBProgre ...

RAD Studio 2010 环境设置(转)

源:RAD Studio 2010 环境设置 最近在使用RAD Studio 2010做一些开发和实验,但在安装了自定义的控件及第三方下载的控件后,在我的工程里经常会提示找不到DCU,为了以后忘记这一 ...

【转载】FPGA 中的latch 锁存器

以下这篇文章讲述了锁存器的一些概念和注意事项.原文标题及链接: FPGA 中的latch 锁存器 - 快乐至永远上的博客 - 与非博客 - 与网 http://www.eefocus.com/liuy ...

python可能会用到的网络基础

网络编程 1.两种构架:(1)C/S构架:client, server (2) B/S构架:browser,server 2.地址相关:(1)MAC地址,物理地址,唯一,但可以更改 (2)ip地址,网 ...

nativefier - 快速把任意网页生成桌面应用程序

使用前端技术开发桌面应用的技术已经相当成熟了,像早先的 NW.js,如今很火的 Electron 等,都可以轻松实现.今天给大家分享的 nativefier 就是基于 Electron 封装的,可以帮 ...

text-decoration和text-indent和text-shadow

text-decoration 属性规定添加到文本的修饰,规定划线的位置.

mysql odbc连接池_Java Mysql连接池配置和案例分析--超时异常和处理相关推荐

  1. java dbcp连接池_Java——DBCP连接池

    连接池 实际开发中"获得连接"或"释放资源"是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection.这样 ...

  2. mysql odbc 10061_关于mysql-connector-odbc无法连接mysql数据库(10061异常)

    关于mysql-connector-odbc无法连接mysql数据库(10061错误) 其实我有两个问题,不知道他们之间有没有什么关系. 最近不知道怎么了,我的mysql好像出了点状况. 问题1: 我 ...

  3. java redis释放连接池_Java 使用连接池操作redis

    构建连接池对象JedisPool JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379); ...

  4. 安装mysql odbc重启mssql_关于php连接mssql:pdo odbc sql server

    关于php连接mssql:pdo odbc sql server 更新时间:2011年07月20日 00:39:33   作者: 研究了很久,终于发现:最新的php 5.3.6中php_mssql.d ...

  5. java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程

    最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...

  6. mysql中文乱码解决_java+mysql中文乱码问题

    乱码问题原因有多种,其中有一种是由于MySQL默认使用 ISO-8859-1 ( 即Latin1 ) 字符集,而JAVA内部使用Unicode编码,因此在JAVA中向MYSQL数据库插入数据时,或者读 ...

  7. java定时线程池_java 定时器线程池(ScheduledThreadPoolExecutor)的实现

    前言 定时器线程池提供了定时执行任务的能力,即可以延迟执行,可以周期性执行.但定时器线程池也还是线程池,最底层实现还是ThreadPoolExecutor,可以参考我的另外一篇文章多线程–精通Thre ...

  8. java多线程线程池_Java多线程——线程池(ThreadPool)

    我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁 ...

  9. mysql ddl 锁_MySQL Online DDL导致全局锁表案例分析

    MySQL Online DDL导致全局锁表案例分析 我这边遇到了什么问题? 线上给某个表执行新增索引SQL, 然后整个数据CPU打到100%, 连接数暴增到极限, 最后导致所有访问数据库的应用都奔溃 ...

最新文章

  1. 云计算自动化对于虚拟化环境意味着什么?
  2. android layout 工具栏,没有工具栏的Android CollapsingToolbarLayout在某个点停止而不是完全关闭...
  3. CompletableFuture介绍
  4. 下拉框_教你封装 Element Tree 树状下拉框
  5. 关于shared_from_this的转换
  6. Java EE业务处理流程与XML的引入
  7. 小米路由器r1d刷第三方_好物推荐 篇三:服役多年的小米路由器R1D准备让他退休, 小米路由R3D开始上岗...
  8. html网页url伪静态,静态、动态、伪静态三种URL表形式优缺点介绍
  9. 2022-2028年中国电子政务行业投资策略探讨及市场规模预测报告
  10. 一个简单的透视游戏的编写
  11. Drools教程(基础篇)—— Eclipse插件安装
  12. 使用git上传代码遇到关于remote: Support for password authentication was removed on August 13, 2021.的问题
  13. Excel如何实现多条件计数统计
  14. Win10不进行操作很快自动睡眠、休眠的解决方法
  15. golang的内存回收策略
  16. bash:/home/xxxx/catikin_ws/setup.bash:没有那个文件或者目录
  17. 波音737连续坠毁,AI要背锅?
  18. 面对黑客攻击,京东数科WAF建设这样做!
  19. Pyecharts3D图:常见的3D图
  20. 决策树用于股票分析整体介绍

热门文章

  1. concurrent 底层_JDK1.8 util-concurrent-ConcurrentLinkedQueue源码分析
  2. 华为harmonyOS开发者日,华为首届HarmonyOS开发者创新大赛收官
  3. Linux 用户及权限详解
  4. Codeforces Round #372 (Div. 1) B. Complete The Graph
  5. 将php分页类YII绑定框架,就需要改变风格的基础
  6. 关于YUV格式的一些总结
  7. python open w_python-文件操作示例
  8. rtmp rtsp 区别_鱼胶粉和吉利丁粉的区别
  9. github项目下载与提交
  10. 深入剖析Android音频(四)AudioTrack