热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

dbcp3连接mysql并发_一次项目实践中DBCP数据库连接池性能优化

关于数据库连接池DBCP的关注源于刚刚结束的一轮测试,测试内容是衡量某Webserver服务创建用户接口的性能。这是一款典型的tomcat应用,使用的测

关于数据库连接池DBCP的关注源于刚刚结束的一轮测试,测试内容是衡量某Webserver服务创建用户接口的性能。这是一款典型的tomcat应用,使用的测试工具是Grinder。DBCP作为tomcat服务器常用的数据库连接池,其性能表现直接关乎应用的性能。

1.遇到的问题

当并发量增加到100时,该接口出现瓶颈,此时TPS接近400,如下图。但是服务端CPU和内存等资源并未达到瓶颈,服务器CPU使用率仅为30%,内存使用率为40%。监控到的javaMethod慢方法为incrAppAccountsSize(),该方法的平均响应时间达206ms。该方法的功能是增加app下的用户数,每当我们在该app下创建一个用户,相应app的总用户数就会加1,缓存中响应的数据也会更新。因此该方法涉及数据库和redis的相关操作。

a875582def371e3d54f8e63d40d0bede.png数据库的插入操作通常比较耗时,添加数据库监控后,该接口相关sql语句执行时间如下,可见相关操作的sql语句的平均耗时在20ms左右,然而慢方法的耗时却在200ms左右,因此性能瓶颈不在sql语句。

27425231877288a734e3c8a05ca0228b.png因此有必要分析下代码执行过程中的堆栈信息,看看慢方法涉及哪些调用。通过jstack dump出现场的堆栈信息如下。

5cdab3bbf16ff171f9e6fd8daba1d1cc.png

2.数据库连接池DBCP

众所周知,数据库的最大连接数是有限的,服务端与数据库建立连接的过程也是非常消耗资源的,因此高效利用数据库连接是非常必要的。java提供了一套专门与数据库打交道的api--jdbc,基于jdbc开发人员可以实现服务端与数据库端的通信。每次执行数据库操作通常需要经历建立数据库连接、执行数据库操作、断开数据库连接三步。当数据库并发访问量大时或请求频繁时,频繁的建立连接再断开连接会给服务端带来很大的额外开销,严重制约着服务端的性能。

因此,数据库连接需要一套维护策略,基于不同的维护策略出现了很多开源的数据库连接组件,DBCP(DataBase Connection Pool)就是其中一个,也据信是目前性能最好的数据库连接组件。除了DBCP以外还有C3P0,、proxool等也是比较常见的。在一定的维护策略下,数据库连接可以实现复用以及再回收。DBCP的使用很简单引入commons-dbcp依赖,并配置好相关参数即可。DBCP的相关配置参数如下,

maxActive:最大连接数

maxIdle:最大空闲连接数

minIdle:最小空闲连接数

initialSize:初始连接数

minEvictableIdleTimeMillis:对连接进行有效性校验的周期

maxActive的值通常根据自己应用的峰值并发量进行设置,当并发量高于该值后超过的请求会排队等待连接释放;当并发量介于maxIdle和maxActive之间时,使用结束的连接会被立即断开,新来的请求会重新创建连接;当并发量介于minIdle和maxIdle之间时,新来的请求会从连接池充获取一个已经建立的且空闲的连接,迅速实现连接复用。因此通常情况下应用的并发量应该维持在minIdle与maxIdle之间。这样才能保证新来的请求迅速获取一个已经建立的连接。通常情况下initialSize会小于或等于minIdle当服务器重启后服务器会与数据库节点保持initialSize个连接,当并发量超多initialSize后连接数会依次上涨至minIdle、maxIdle和maxActive,当连接空闲时根据回收策略连接会被回收,并最终回落至minIdle。

3.问题分析

结合DBCP以及第一节中利用jstack dump出的堆栈信息,可见服务端一直处于连接断开的过程中。而DBCP建立连接的速度比断开连接快,因此服务端一直卡在资源释放的阶段。服务端的DBCP的相关配置如下:

maxActive:500

maxIdle:50

minIdle:30

initialSize:30

并发访问量为160,在maxIdle和maxActive之间,因此当一个连接使用结束后由于当前连接数大于maxIdle连接无法被复用会被立即断开,新来一个请求也无法获取一个空闲的连接需要重新建立一个新的连接,由于断开连接的响应时间较慢,断开连接都在等待资源的释放,大量的线程出现排队,这样就出现了通过jstack看到的,线程被block住的现象。针对这种问题有两种优化思路:

提高连接池的复用率。

增加空闲连接的数量。

通过提高连接复用率来解决这种问题的前提是数据库操作的执行速度够快,监控数据库sql执行速度在20ms左右,如果多个数据库操作排队对性能影响不大,基于这种思路可以降低maxActive的值。当并发访问量达到上限后不再分配更多的数据库连接,而是等待前一个连接使用结束,由于maxActive与maxIdle的差值变小,因此需要断开的连接的数量变少,这样可以避免由于连接的断开性能较差导致大量线程被block住的情况。将maxActive的值修改为100后,160并发创建用户的性能如下。

d18ef8d9a38f6cacd8cfb2b11f573c3c.png

慢方法incrAppAccountsSize的响应时间由800多毫秒,减小到80多毫秒,通过jstack抓取现场堆栈信息可以看到有些线程被block在getConnection状态,线程获取连接出现排队,但是由于数据库操作响应时间很快,这种线程被block在getConnection状态的时间并不长。

通过增加空闲连接的数量来也可以改善频繁断开连接所带来的性能问题,由于当前并发量超过了最大空闲连接数,增加空闲连接数可以减少断开连接的数量,提高复用率。但是增加空闲连接的数量会占用宝贵的数据库连接资源,影响服务扩展。将maxIdle大小调整为200后,160并发创建用户的性能如下。

799e6c35dd1c283235574ae44ab8cc1c.png

以上数据表明,通过这两种方式可以有效的提高慢方法的响应时间。通过增加空闲连接的数量带来的性能提升优于增加复用率,因为增加空闲连接的数量可以避免排队耗时。单纯的增加maxIdle的值会使得空闲连接的数量增加。并发连接也不会一直维持在maxIdle这个水平,如果当前的并发压力减小了,DBCP本身也有连接回收策略。空闲连接的回收是通过这两个参数来实现的。

minEvictableIdleTimeMillis:空闲连接过期时间

timeBetweenEvictionRunsMillis:空闲连接回收触发周期

当连接池中的空闲连接空闲了minEvictableIdleTimeMillis这么长时间后,该连接会被置为可回收状态。DBCP会按照timeBetweenEvictionRunsMillis的时间进行周期回收。最在没有额外压力的前提下终空闲连接稳定到minIdle水平。

4.总结

数据库连接池的maxIdle和maxActive之间的差值不宜不过大。如果数据库操作响应时间很快的话可以提高连接复用率,但是这么做会出现连接排队的情况。如果数据库操作的响应时间较慢可以增加空闲连接的数量。由于数据库总的连接数是一定的,单个服务的具体数据库连接配额应该根据服务的压力进行调整。

原创文章

禁止其他公众账号转载

e3e8d3ac84175ed054d2e452dea8ced8.gif



推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
author-avatar
文伯雅寧19
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有