
<p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2021%2F0429%2Fffj00qsb11l001dc000hs00axm.jpg&thumbnail=660x&quality=80&type=jpg"/><br/></p><p>关键词:分布式关系型数据库、分布式数据库 MySQL、分布式数据库 分片</p><p>最近用户在使用 druid 连接池连接 dble 时,应用会有不定时出现下面的错误:</p><p>com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failureThe last packet successfully received from the server was 425,724 milliseconds ago. The last packet sent successfully to the server was 425,725 milliseconds ago.</p><p>这种错误还是很常见的,猜测是应用拿到了已经 close 的连接并继续使用从而引发上面的问题。因此,我们想开启 druid 中的对空闲连接检测的机制。</p><p>在查询文档的过程中,发现了两个参数,分别是 testWhileIdle 和 keepAlive(1.0.28 版本引入),那到底这两个参数有什么区别?</p><p>下面我们使用 1.1.13 版本的 druid 做一个测试。</p><p>结论</p><p><ul><li>开启 testWhileIdle 之后,druid 不会在 timeBetweenEvictionRunsMillis 指定的周期内检测空闲连接的有效性,而是在连接取出时对连接做一下检测。</li><li>开启 keepAlive 之后,druid 会在 timeBetweenEvictionRunsMillis 指定的周期内检测空闲连接的有效性。</li></ul></p><p>因此在实际使用中,建议开启 keepAlive 参数用于对空闲连接做有效性检测。Druid 中 testWhileIdle 和普通的连接池(DBCP 等)所表达的含义并不相同,使用时候需要慎重。</p><p>详细测试过程</p><p>测试程序原理是:首先初始化 druid 连接池,使其中有一个空闲连接。我们设置 TimeBetweenEvictionRunsMillis 为 10s,分别打印 10s 前后连接池中连接的信息。连接信息中 LastActiveTime 这个属性表示这条连接上次被使用的时间。通过观察前后两次打印的 LastActiveTime 是否有差别,来推断期间是否有对连接下发语句进行过有效性检测。</p><p>测试程序:</p><p>public static void main(String[] args) { try { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://127.0.0.1:8066/testdb2?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8"); dataSource.setUsername("root"); dataSource.setPassword(""); // 开启 testWhileIdle 参数 // dataSource.setTestWhileIdle(true); // 开启 keepalive 参数 dataSource.setKeepAlive(true); // 设置检测时间为 10s dataSource.setTimeBetweenEvictionRunsMillis(10 * 1000); dataSource.setMinEvictableIdleTimeMillis(5000); dataSource.setValidationQuery("select 'x'"); dataSource.setMinIdle(1); dataSource.setMaxActive(1); Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement("select 1"); ps.close(); conn.close(); // 第一次结果 System.out.println(dataSource.dump()); Thread.sleep(12000); // 第二次结果 System.out.println(dataSource.dump()); } catch (InterruptedException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }}</p><p><strong>开启 keepalive 参数</strong></p><p>第一次结果:</p><p>{ CreateTime:"2021-03-23 18:46:59", ActiveCount:0, PoolingCount:1, CreateCount:1, DestroyCount:0, CloseCount:1, ConnectCount:1, Connections:[ {ID:, ConnectTime:"2021-03-23 18:46:59", UseCount:1, LastActiveTime:"2021-03-23 18:47:00"} ]}</p><p>第二次结果:</p><p>{ CreateTime:"2021-03-23 18:46:59", ActiveCount:0, PoolingCount:1, CreateCount:1, DestroyCount:0, CloseCount:1, ConnectCount:1, Connections:[ {ID:, ConnectTime:"2021-03-23 18:46:59", UseCount:1, LastActiveTime:"2021-03-23 18:47:09"} ]}</p><p>观察第一次结果和第二次结果中 Connections 的 LastActiveTime 值,分别是 2021-03-23 18:47:00 和 2021-03-23 18:47:09,发现两个值变化,可以推断出 10s 內有对连接下发语句进行过有效性检测。</p><p><strong>开启 testWhileIdle 参数</strong></p><p>第一次结果:</p><p>{ CreateTime:"2021-03-23 18:52:38", ActiveCount:0, PoolingCount:1, CreateCount:1, DestroyCount:0, CloseCount:1, ConnectCount:1, Connections:[ {ID:, ConnectTime:"2021-03-23 18:52:39", UseCount:1, LastActiveTime:"2021-03-23 18:52:39"} ]}</p><p>第二次结果:</p><p>{ CreateTime:"2021-03-23 18:52:38", ActiveCount:0, PoolingCount:1, CreateCount:1, DestroyCount:0, CloseCount:1, ConnectCount:1, Connections:[ {ID:, ConnectTime:"2021-03-23 18:52:39", UseCount:1, LastActiveTime:"2021-03-23 18:52:39"} ]}</p><p>观察第一次结果和第二次结果中 Connections 的 LastActiveTime 值,分别是 2021-03-23 18:52:39 和 2021-03-23 18:52:39,发现两个值没有变化,可以推断出 10s 內没有对连接下发语句进行过有效性检测。</p><p>关键词:分布式关系型数据库、分布式数据库 MySQL、分布式数据库 分片</p>
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/153457.html