线程池实现填充短信

在最近几个月中,我们一直看到很小但持续的操作失败,但有一个奇怪的异常– 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轴上显示)。 默认的经验法则是,左侧的条形越高,效果越好。 第四图表是瀑布图,其中每个水平线表示一个DB操作。 棕色表示等待获取连接的时间,绿色表示执行数据库操作的时间,蓝色表示将连接返回到连接池的时间。

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

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

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

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

稍后我们可能会尝试使用公平锁定来修补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

线程池实现填充短信

线程池实现填充短信_填充一个池需要多少个线程?相关推荐

  1. 自动填充短信验证码实现方式

    自动填充短信验证码 短信验证码是大部分软件里面都存在的功能,同时为了避免用户自己输入导致的繁琐操作,有一部分app设计者将其设置成了自动填充的方式,方便用户操作那么这种方式是什么实现的呢. 利用广播接 ...

  2. Android自动填充短信验证码

    自动拦截短信实际上就是在系统注册一个BroadcastReceiver,然后通过设置拦截短信的: filter.addAction("android.provider.Telephony.S ...

  3. android自动接收并填充短信验证码

    这只是部分代码.大家直接拷贝相应代码到自己的activity里对应位置即可. public EditText re_check; private BroadcastReceiver smsReceiv ...

  4. 用电脑发短信_重磅!一个软件实现电脑上接打手机电话、收发短信、传文件、屏幕镜像!...

    点击箭头处"蓝色字",关注我们哦!! Dell Mobile Connect 本身是一款专门为 Dell 指定设备提供的专门为计算机与 iOS 或者 Android 智能手机之间进 ...

  5. 用电脑发短信_丢掉你的手机数据线吧!用这个软件轻松在任何设备互传文件

    在介绍了两期跨平台文件互传解决方案(请翻阅我最近的几篇文章)之后,总有些意犹未尽,因为有太多的好软件了.但是,前几期介绍的软件,侧重于文件传输.例如手机和手机,手机和电脑互传图片,文档,视频,歌曲等资 ...

  6. 移动html特殊链接【打电话_发短信_发邮件】

    如果需要在移动浏览器中实现拨打电话,调用sms,发送email等功能,移动手机WEB页面(HTML5)Javascript提供的接口是一个好办法. 采用url链接的方式,实现在Safari iOS,A ...

  7. java at发短信_发送短信(1)

    //发送短信 @Override public int sendSms(String mobile){ int smsCode=0, ret=0; String temp; boolean resul ...

  8. iphone查看删除的短信_想要恢复已经删除的的短信怎么办?

    阅读本文前,请您先点击上面的蓝色字体,再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 手机短信删除了怎么办?删除的短信如何恢复?这已经不 ...

  9. iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既 ...

最新文章

  1. 深度学习与计算机视觉系列(9)_串一串神经网络之动手实现小例子
  2. Mysql VARCHAR(X) vs TEXT
  3. 苹果首席设计官离职!这个被称为“强纳肾”的男人,设计了iMac、iPhone等无数产品...
  4. 2016年3月26日作业
  5. 056_Unicode字符官方标准七
  6. canvas 绘制跟随鼠标移动的线条
  7. Linux学习:第三章-Linux常用命令-2
  8. 蔡高厅老师 - 高等数学阅读笔记 - 04 - 函数的连续性(18、19、20、21)
  9. 关于百度地图API的地图坐标转换问题
  10. FlashFTP教程
  11. 毕业两年程序员Java学习路线
  12. OpenCV+Python 彩色图片的 BGR、灰度图、HSV分量图显示的程序
  13. Linux 8723be无线网卡,解决rtl8723be无线网卡驱动频繁断网问题
  14. 铁矿石再度领跌商品,LPG认沽上涨3倍,MTO季节性上涨2022.6.22
  15. 网络聊天中的英语简写
  16. No.01统计学之数据的描述性统计
  17. 云图数字iOS客户端
  18. 【数字图像处理】特征提取轮廓特征对黑色素瘤恶性/良性分类
  19. 接收字符大写转化为对应的小写
  20. MySQL数据库的常用命令

热门文章

  1. 12、数据库的设计范式
  2. 如何quot;优雅quot;地终止一个线程?
  3. 如何设计一个安全的登录流程
  4. 你可能不知道的 10 条 SQL 技巧
  5. php如何接收前端返回的各种类型的数据
  6. 如何求解两个数的最大公约数
  7. Springboot 2.x 单元测试 JUnit 5
  8. python django 是啥_python的django做什么的
  9. java抽取pdf_java 抽取 word,pdf 的四种武器
  10. AQS的细节--自用,非正常教程