填充一个池需要多少个线程?

近几个月来,我们一直看到一小部分但持续的操作失败,并带有一个奇怪的异常– org.springframework.jdbc.CannotGetJdbcConnectionException –“无法获得JDBC连接; 嵌套异常是java.sql.SQLException:客户端尝试检出Connection的尝试已超时。 ”

我们自然的假设是,我们的C3P0连接池存在某种争用,试图获取连接的客户端必须等待该争用可用。 我们最好的猜测是正是这种争用导致了超时。

因此,当然,我们要做的第一件事是增加连接池中的最大连接数。 但是,无论我们将限制设置得多么高,它都无济于事。 然后,我们尝试更改连接的超时参数。 那没有产生任何更好的结果。

此时,情报已经确定下来,并且由于猜测似乎没有用,因此我们决定进行测量。 在连接池上使用一个简单的包装程序,我们看到即使连接池中有空闲连接,我们仍然会得到签出超时。

调查连接池开销

为了研究连接池开销,我们执行了一个基准测试,该基准测试由6个回合组成,每个回合包括20,000个SQL操作(读/写比为1:10),使用20个线程和20个连接的连接池来执行。 使用具有20个连接的池使用20个线程意味着资源(连接)上没有争用。 因此,任何开销都是由连接池本身引起的。

我们忽略了第一次(预热)运行的结果,而取了随后5次运行的统计数据。 从这些数据中,我们收集连接签出时间,连接释放时间和总池开销。

基准项目代码可以在以下位置找到: https : //github.com/yoavaa/connection-pool-benchmark

我们测试了3个不同的连接池:

  • C3P0 – com.mchange:c3p0:0.9.5-pre3 – C3P0DataSourceBenchmark类
  • Bone CP – com.jolbox:bonecp:0.8.0-rc1 –类BoneDataSourceBenchmark
  • Apache DBCP – commons-dbcp:commons-dbcp:1.4 –类DbcpDataSourceBenchmark

(在该项目中,还有一个我自己的实验性异步池的基准测试-https: //github.com/yoavaa/async-connection-pool 。但是,出于本文的目的,我将忽略它)。

为了自己运行基准测试,您应该使用下表设置MySQL

CREATE TABLE item (file_name     varchar(100) NOT NULL,user_guid     varchar(50) NOT NULL,media_type    varchar(16) NOT NULL,date_created  datetime NOT NULL,date_updated  timestamp AUTO_INCREMENT NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY(file_name)
)

然后更新Credentials对象以指向此MySQL安装。

运行基准测试时,示例结果如下所示:

run, param, total time, errors, under 1000 nSec,1000 nSec - 3200 nSec,3200 nSec - 10 µSec,10 µSec - 32 µSec,32 µSec - 100 µSec,100 µSec - 320 µSec,320 µSec - 1000 µSec,1000 µSec - 3200 µSec,3200 µSec - 10 mSec,10 mSec - 32 mSec,32 mSec - 100 mSec,100 mSec - 320 mSec,320 mSec - 1000 mSec,1000 mSec - 3200 mSec,other
0, acquire,29587,0,0,5,1625,8132,738,660,1332,1787,2062,2048,1430,181,0,0,0
0, execution, , ,0,0,0,0,0,0,0,1848,6566,6456,5078,52,0,0,0
0, release, , ,0,8,6416,9848,3110,68,77,115,124,148,75,11,0,0,0
0, overhead, , ,0,0,49,4573,5459,711,1399,1812,2142,2157,1498,200,0,0,0
1, acquire,27941,0,0,125,8153,499,658,829,1588,2255,2470,2377,1013,33,0,0,0
1, execution, , ,0,0,0,0,0,0,6,1730,6105,6768,5368,23,0,0,0
1, release, , ,0,49,15722,3733,55,42,69,91,123,101,14,1,0,0,0
1, overhead, , ,0,0,2497,5819,869,830,1610,2303,2545,2448,1042,37,0,0,0

此信息已导入Excel文件(也包含在基准项目中)以进行分析。

C3P0

最初在C3P0中,我们在生产环境中看到了原始异常。 让我们看看它如何执行:

阅读图表:

前三个图表(获取,发布,开销)是基于性能的存储桶图表。 Y轴表示在一定时间范围内完成的操作数(在X轴上显示)。 默认的经验法则是,左侧的条形越高,效果越好。 第4 图表是瀑布图,其中每个水平线表示一个DB操作。 棕色表示等待获取连接的时间,绿色表示执行数据库操作的时间,蓝色表示将连接返回到连接池的时间。

从图表中可以看出,通常,C3P0在3.2-10微秒内获得连接,并在3.2-10微秒内释放连接。 那绝对是一些令人印象深刻的表现。 但是,C3P0在约3.2-32毫秒处还有另一个峰值,而长尾巴则高达320-1000毫秒。 正是第二个高峰导致了我们的例外。

C3P0怎么了? 是什么原因导致了这种极小但相当大的超长操作百分比,而大多数时候却表现惊人? 纵观4 图可以为我们指出了答案的方向。

第4 图表从左上角到右下角有一条清晰的对角线,表明总体上,连接获取是按顺序开始的。 但是我们可以识别出一些奇怪的东西–我们可以看到棕色的三角形,表示当多个线程试图获取连接时,第一个线程比随后的线程等待更多的时间。 这转化为用于获取连接的两个性能“组”。 一些线程极其快速地获得连接,而有些线程则饿死等待连接,而较后的线程的请求则得到了较早的答复。

早期线程比后续线程等待更长的时间的这种行为意味着不公平的同步。 事实上,挖掘到C3P0代码时,我们已经看到了收购的连接的过程中,C3P0使用“ 同步 ”关键字三次。 在Java中,“ synced ”关键字创建了不公平的锁定,这可能导致线程饥饿。

稍后我们可能会尝试使用公平锁定来修补C3P0。 如果这样做,我们自然会分享我们的发现。

此基准测试的C3P0配置:

  • 最小泳池大小:20
  • 初始池大小:20
  • 泳池最大大小:20
  • 采集增量:10
  • 辅助线程数:6

骨CP

我们在Wix上尝试了BoneCP,但结果却不尽相同,因此目前尚不确定我们是否喜欢它。 尽管分析并不全面,但我们将BoneCP基准测试的结果包括在这些帖子中。

查看图表,我们可以看到Bone的连接捕获性能非常出色–大多数操作在3.2微秒内完成,比C3P0快得多。 但是,我们还观察到连接释放时间很长,大约1-10毫秒,太高了。 我们还观察到Bone的操作很长,开销高达320毫秒。

从数据来看,在正常情况和“极端”情况下,BoneCP似乎都比C3P0好。 但是,如图表所示,差异并不大。 查看第4 图表,我们看到与C3P0相比,棕色更少(因为连接获取更好),但出现了蓝线,表明线程等待连接释放的时间。

如上所述,由于我们对使用BoneCP充其量是矛盾的,因此我们没有投入大量资源来分析此连接池的性能问题。

Apache DBCP

Apache DBCP被称为古老的数据源。 让我们来看看与其他两个相比的情况。

显而易见的是-DBCP性能优于C3P0和Bone。 在所有方面,无论是在连接检查时间,连接释放时间还是瀑布图形式方面,它都优于其他方法。

那么您应该使用什么数据源?

好吧,这是一个不平凡的问题。 显然,就连接池性能而言,我们显然是赢家– DBCP。 似乎C3P0应该很容易修复,我们可以尝试一下。

但是,请务必记住,此调查的范围仅限于实际连接获取/释放的性能。 实际的数据源选择是一个更复杂的问题。 例如,该基准测试忽略了一些重要方面,例如池的增长和缩小,网络错误的处理,数据库故障时的故障转移等等。

参考: 填充一个池需要多少个线程? 来自我们的JCG合作伙伴 Yoav Abrahami,来自Wix IO博客。

翻译自: https://www.javacodegeeks.com/2013/06/how-many-threads-does-it-take-to-fill-a-pool.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

@font-face 用字体画图标

HTML 1 <body>2 <!-- ul.layout>li*5>a[href#]>i.icon -->3 <!-- Sublime Text 快捷拼写 -->4 <ul class"layout">5 <li><a href"#"><i class"icon">&#xe601;</…

java mapfile_基于文件的数据结构:关于MapFile

MapFile是已经排过序的SequenceFile&#xff0c;它有索引&#xff0c;所以可以按键查找1.MapFile的写操作MapFile的写操作类似于SequenceFile的写操作。新建一个MapFile.Writer实例&#xff0c;然后调用append()方法顺序写入文件内容。如果不按顺序写入&#xff0c;就抛出一个I…

linux scp 命令

scp 命令 scp 命令 意思是 secure copy 即安全拷贝&#xff0c;可以把它看做是 cp 命令的高级版&#xff0c;可以跨主机拷贝。 经常用来在局域网内不同主机之间分享文件&#xff0c;或者在本机与远程主机中分享文件。 在使用的时候就像使用cp 命令一样&#xff0c;第一个参数是…

工厂设计模式–一种有效的方法

如您所知&#xff0c;工厂方法模式或俗称工厂设计模式是“创意设计模式”类别下的一种设计模式。 模式背后的基本原理是&#xff0c;在运行时&#xff0c;我们根据传递的参数获得类似类型的对象。 关于这种模式有很多文章&#xff0c;开发人员可以通过各种方式来实现它。 在本文…

java 循环依赖_解决Java循环依赖的问题

最近看到一个问题&#xff1a;如果有两个类A和B&#xff0c;A类中有一个B的对象b&#xff0c;B类中有一个A的对象a&#xff0c;那么如何解决这两个类的相互依赖关系呢&#xff0c;几天就给大家说一下Java的循环依赖&#xff0c;raksmart服务器。举个栗子1&#xff1a;可以看到A…

CSS块元素水平垂直居中的实现技巧

针对之前遇到过的一些特殊样式的实现&#xff0c;我今天做个总结&#xff0c;目的有二&#xff1a;一是将这些方法记录下来&#xff0c;以便将来需要用到时查找使用。二为将这些大神们智慧的结晶发扬光大&#xff0c;让广大前端程序猿们能够少走弯路。此贴为更新帖&#xff0c;…

Intellij IDEA 将工程转换成maven工程 详解

1> 右键工程&#xff0c;点击 Add Framework Support2> 选中 Maven&#xff0c;再点击 OK3> 工程根目录自动生成 pom.xml 文件&#xff0c;这样 工程就支持 Maven版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 http://blog.csdn.net/che…

设置Apache Hadoop多节点集群

我们正在分享有关在基于Linux的机器&#xff08;多节点&#xff09;上安装Apache Hadoop的经验。 在这里&#xff0c;我们还将分享我们在各种故障排除方面的经验&#xff0c;并在将来进行更新。 用户创建和其他配置步骤– 我们首先在每个集群中添加一个专用的Hadoop系统用户。…

数据结构(七)排序---直接插入排序(稳定)

经典排序算法----直接插入排序算法及其改进&#xff08;稳定&#xff09; 定义&#xff1a; 直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中&#xff0c;从而得到一个新的&#xff0c;记录数加一的有序表。 实现思想 我们预留了一个哨兵&#xff0c;这里我们将…

CSS3中的透明属性opacity的用法实例

实例设置 div 元素的不透明级别&#xff1a;div{opacity:0.5;}完整例子&#xff1a;<!DOCTYPE html><html><head><style> div{background-color:red;opacity:0.5;filter:Alpha(opacity50); /* IE8 以及更早的浏览器 */}</style></head><…

java嵌套类型 无法隐藏外层类型_java内部类深入详解 内部类的分类 特点 定义方式 使用...

java内部类 内部类的分类 特点 定义方式 使用 外部类调用内部类 多层嵌套内部类 内部类访问外部类属性 接口中的内部类 内部类的继承 内部类的覆盖 局部内部类 成员内部类 静态内部类 匿名内部类内部类定义将一个类定义放到另一个类的内部,这就是内部类内部类与组合是完…

java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件。)

在使用MyBatis的逆向工程生成代码时&#xff0c;一直报错java.io.FileNotFoundException: generatorConfig.xml (系统找不到指定的文件。)&#xff0c;如图 文件结构如下&#xff1a; 代码如下&#xff1a; import java.io.File; import java.util.ArrayList; import java.util…

单例设计模式–鸟瞰

几天前&#xff0c;当我回到家乡时&#xff0c;我的一位来自同事的大三学生参加了一家跨国公司的采访&#xff0c;在采访过程中受了重伤。 我的意思是&#xff0c;由于面试小组提出的难题&#xff0c;他无法使面试合格。 当我回到班加罗尔时&#xff0c;他分享了他在技术面试中…

软件实践第一步——自我介绍

031602631&#xff1b;我是超爱美食的苏韫月&#xff1b;我的爱好是品尝所能接触到的所有甜点&#xff08;迟早&#xff01;&#xff09;&#xff1b;我最近新宠&#xff1a;拌面加扁肉&#xff08;京园淳百味&#xff09;&#xff1b;时隔一年我又回归心惊胆颤写博客文的日子。…

CSS3中使用translate() 方法实现元素位置的移动

translate() 方法通过 translate() 方法&#xff0c;元素从其当前位置移动&#xff0c;根据给定的 left&#xff08;x 坐标&#xff09; 和 top&#xff08;y 坐标&#xff09; 位置参数&#xff1a;实例div{transform: translate(50px,100px);-ms-transform: translate(50px,1…

java机器学习库_Amazon Deep Java Library——Java 机器学习工具箱

近年来&#xff0c;人们对机器学习的兴趣稳步增长。具体来说&#xff0c;现在&#xff0c;企业在各种各样的场景中使用机器学习进行图像识别。它在汽车工业、医疗保健、安全、零售、仓库、农场和农业的自动化产品跟踪、食品识别&#xff0c;甚至通过手机摄像头进行实时翻译等方…

阻抗计算

si9000也可以算 一般有点差异&#xff0c;板厂可以微调 加上滤油&#xff0c;实际阻抗会降低2-3欧 影响最大的是层厚 先选择最薄的芯板&#xff0c;注意差分线的阻抗匹配&#xff0c;间距越小&#xff0c;阻抗小&#xff0c; 转载于:https://www.cnblogs.com/IotI/p/8587277.h…

Spring Data Solr教程:动态查询

Solr通常被称为搜索服务器&#xff0c;我们可以在实现全文搜索功能时使用它。 但是&#xff0c;当我们实现从搜索表单获取其输入的搜索功能时&#xff0c;利用Solr的性能通常是明智的。 在这种情况下&#xff0c;执行的搜索查询取决于收到的输入。 这意味着查询参数的数量取决…

[cdq分治][树状数组] Jzoj P4419 hole

Description GFS打算去郊外建所别墅&#xff0c;享受生活&#xff0c;于是他耗费巨资买下了一块风水宝地&#xff0c;但令他震惊的是&#xff0c;一群DSJ对GFS的富贵生活深恶痛绝&#xff0c;决定打洞以搞破坏。现在我们简化一下这个问题&#xff0c;在这片土地上会按顺序发生一…

关于CSS3实现响应式布局的一些概念和术语

响应式布局也被应用到网站前端开发中&#xff0c;在国内这一词想必是非常火吧&#xff0c;那网站为什么要使用响应式布局呢&#xff1f;原因和其他创意性的生活用品基本上是一样的&#xff0c;处于对人力物力财力的节省和对生活富有诗意的一种追求。在人力物力和财力有限的情况…