如何合理设置数据库连接池的大小小

君,已阅读到文档的结尾了呢~~
was使用及参数设置was使
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
was使用及参数设置
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口966,690 六月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
线程池规模调优
线程池规模调优
Kirk Pepperdine
注意:,500+CTO技聚重新定义技术领导力!
相关厂商内容
相关赞助商
QCon全球软件开发大会上海站,日-22日,上海宝华万豪酒店,!
利特尔法则(Little&s law)
利特尔法则(Little&s law)是说,一个系统请求数等于请求的到达率与平均每个单独请求花费的时间之乘积。整个法则在我们日常生活中很常见,令人吃惊的是直到上世纪50年代才提出来,然后到60年代才被证明。下面有个例子,是实际生活中利特尔法则的一种形式。你是否曾经排队,然后试图计算要等多长时间?你可能考虑排队的人数,然后快速算一下服务队列前面的人需要花多长时间。此时,你可以将两个值相乘,产生你在队列时间的估算。若不看队列的长度,你记住新人加入队列的频率,然后乘以服务时间,照样可以知道在队列中或被服务的人平均数。
有很多其它相似的游戏,同样适用于利特尔法则(Little&s law),可以回答其它的问题,如&在队列中等待服务的一个人平均所花时间?&,诸如此类。
图1 利特尔法则(Little&s law)
同样,我们可以使用利特尔法则(Little&s law)来判定线程池大小。我们只需计算请求到达率和请求处理的平均时间。然后,将上述值放到利特尔法则(Little&s law)就可以算出系统平均请求数。若请求数小于我们线程池的大小,就相应地减小线程池的大小。与之相反,如果请求数大于线程池大小,事情就有点复杂了。
当遇到有更多请求待处理的情况时,我们首先需要评估系统是否有足够的能力支持更大的线程池。准确评估的前提是,我们必须评估哪些资源会限制应用程序的扩展能力。在本文中,我们将假定是CPU,而在实际中可能是其它资源。最简单的情况是,我们有足够的空间增加线程池的大小。若没有的话,你不得不考虑其它选项,如软件调优、增加硬件,或者调优并增加硬件。
让我们通过套接字发起和执行的请求典型工作流程来解释上述逻辑。执行过程中,需要获取数据或其他资源,直到结果从客户端返回。在我们的演示中,服务器通过执行一个标准工作单元来模拟负载,该工作单元在CPU敏感任务与解析数据库或其它外部数据源的数据来回切换。演示时,让我们通过计算无理数的小数位如Pi或2的平方根来模拟CPU密集型计算。Thread.sleep常用来模拟外部数据源的调用。 线程池将用于控制服务器上的活跃请求数。
为了监控java.util.concurrent (j.u.c)中线程池的选择情况,我们需要增加仪表盘。现实中,我们可以通过使用切面、ASM或者其它二进制检测技术检测使用j.u.c.ThreadPoolExecutor 而填加仪表盘。基于示例目的,我们没有上述技术,而是使用j.u.c.ThreadPoolExecutor 人工扩展来包含必要的监控。
public class InstrumentedThreadPoolExecutor extends ThreadPoolExecutor {
// Keep track of all of the request times
private final ConcurrentHashMap&runnable long ,& timeOfRequest =
new ConcurrentHashMap&&();
private final ThreadLocal&long& startTime = new ThreadLocal&long&();
private long lastArrivalT
// other variables are AtomicLongs and AtomicIntegers
protected void beforeExecute(Thread worker, Runnable task) {
super.beforeExecute(worker, task);
startTime.set(System.nanoTime());
protected void afterExecute(Runnable task, Throwable t) {
totalServiceTime.addAndGet(System.nanoTime() - startTime.get());
totalPoolTime.addAndGet(startTime.get() - timeOfRequest.remove(task));
numberOfRequestsRetired.incrementAndGet();
} finally {
super.afterExecute(task, t);
public void execute(Runnable task) {
long now = System.nanoTime();
numberOfRequests.incrementAndGet();
synchronized (this) {
if (lastArrivalTime != 0L) {
aggregateInterRequestArrivalTime.addAndGet(now - lastArrivalTime);
lastArrivalTime =
timeOfRequest.put(task, now);
super.execute(task);
代码清单1.检测 ThreadPoolExecutor关键代码
上述代码是仪表盘代码的重要部分,我们的服务器将用在ThreadPoolExecutor 部分。重写三个关键执行器方法:beforeExecute,execute和afterExecute,进行数据收集,然后使用MXBean发布数据。让我们看看那每一个方法的工作方式。
执行器的execute方法用于传递请求给执行器。重写该方法可以收集所有的初始时序。我们也能利用该机会跟踪请求之间的时间间隔。由于我们是共享状态,所以该活动需要串行执行。最后委托给父执行器类。
正如名称所提示的,方法executeBefore会在请求执行前得以执行。此时,请求累计的所有时间只是在线程池的等待时间。通常被称为&死亡时间&。该方法执行结束后到afterExecute执行前被称为&服务时间&, 也是能使用利特尔法则(Little&s law)的时间。我们可以使用ThreadLocal存放起始时间。afterExecute 方法用于计算&线程池中时间&,&执行请求的时间,接着注册该&请求已经处理完毕&。
我们还需要一个MXBean来报告性能,该性能数据来自于用于检测ThreadPoolExecutor的收集计数器。这是MXBean ExecutorServiceMonitor 的工作(参考代码清单2)。
public class ExecutorServiceMonitor
implements ExecutorServiceMonitorMXBean {
public double getRequestPerSecondRetirementRate() {
return (double) getNumberOfRequestsRetired() /
fromNanoToSeconds(threadPool.getAggregateInterRequestArrivalTime());
public double getAverageServiceTime() {
return fromNanoToSeconds(threadPool.getTotalServiceTime()) /
(double)getNumberOfRequestsRetired();
public double getAverageTimeWaitingInPool() {
return fromNanoToSeconds(this.threadPool.getTotalPoolTime()) /
(double) this.getNumberOfRequestsRetired();
public double getAverageResponseTime() {
return this.getAverageServiceTime() +
this.getAverageTimeWaitingInPool();
public double getEstimatedAverageNumberOfActiveRequests() {
return getRequestPerSecondRetirementRate() * (getAverageServiceTime() +
getAverageTimeWaitingInPool());
public double getRatioOfDeadTimeToResponseTime() {
double poolTime = (double) this.threadPool.getTotalPoolTime();
return poolTime /
(poolTime + (double)threadPool.getTotalServiceTime());
public double v() {
return getEstimatedAverageNumberOfActiveRequests() /
(double) Runtime.getRuntime().availableProcessors();
代码清单2. ExecutorServiceMonitor类关键代码
在代码清单2中,我们可以看到给出问题答案的关键方法,队列是如何使用的? 注意getEstimatedAverageNumberOfActiveRequests()方法是利特尔法则(Little&s law)的实现。在该方法中,在每一个请求离开系统的退出率或观测率乘以服务于请求的平均时间等于系统平均请求数。另两个重要方法是getRatioOfDeadTimeToResponseTime()和getRatioOfDeadTimeToResponseTime()。让我们运行一些实验,看看这些数字相互之间的关系,以及与CPU利用率的关联。
第一个实验只是简单的提供整个过程的流程。小实验的配置是设置&服务器线程池大小&为1,并且仅有一个客户端如上所述的重复发出请求,持续30秒。
图2 1客户端,1服务器线程的结果
图2的视图来自于VisualVM MBean视图的快照和图形化CPU使用率监控器。VisualVM ()是一个开源的工程,支持性能监控及分析的工具。工具使用方法超出了本文的范围。 简单的说,MBean 视图是一个可选的插件,让你访问所有注册于PlatformMBeansServer中的JMX MBeans 。
回到小实验,线程池大小是1。考虑到客户端循环特性,我们可能期望活跃请求的平均数是一个。但是,客户端重发请求需要花时间,因此上述值会小于1,0.98是在预期内的。
下一个值RatioOfDeadTimeToResponseTime 刚超过0.1%。考虑到目前只有一个主动请求与线程池的大小相匹配,上述值预期为0。但是,由于计时器位置和计时精度的偏差,该值很可能是非零值。该值相当小以至于我们可以忽略它的大小。CPU利用率告知我们core值小于1意味着有更多容量来处理更多请求。
在第二个实验中,我们设置线程池大小为1,而发起请求的并发客户端数目调升为10。不出所料,由于同一时刻只会有一个线程工作,所以CPU利用率并没有变化。然而,由于活跃请求数是10,允许客户端相互间不必等待,有可能我们会驳回更多请求。从这一点,我们可以得出结论,只有一个请求是活跃的,我们的队列长度是9。更多说明的是死亡时间占响应时间的比例接近于90%。该数字说明客户端看到的总响应时间的90%花费在线程等待上。如果我们想降低延迟,弹性空间最大的是死亡时间,我们有大量CPU冗余,所以通过增加线程池大小让请求得以处理是安全的做法。
图示 3 一个服务线程处理10个客户端请求的的结果
因为核心数字是4,所以让我们将线程池大小调整为4,运行同样的实验,。
图示4. 4个服务器线程处理10客户端请求的结果
我们再次看到平均请求数是10。不同的是,这次包括处理的请求数跳升过了2000。CPU也有一个接近于饱和的增长,但仍没有到100%。死亡时间占总响应时间的60%,还是比较健康的,这意味着仍有改善空间。我们是否可以继续增加线程池的大小来充分利用剩余CPU处理能力呢?
在最后的实验运行期间,我们把线程池配置为8个线程。从结果来看,与预期一致,平均请求数在10以下,死亡时间占比下降到19%以下,处理的请求数跳升为3621,很健康。CPU利用率接近100%。看起来在当前负载的情况下我们已经接近改善的极限了。这说明8是理想的线程池大小。我们能做出的另一个结论是,若需要减少更多的死亡时间,唯一方式是增加更多CPU或者改善应用程序的CPU效率。
图示5. 8个服务器线程处理10个客户端请求的结果
理论与现实
上述实验可能会引起各种批评,其中之一是有些过度简化,大型应用程序不太可能只存在一个线程或者一个连接池。实际上,很多应用程序在通信技术中往往拥有多个连接池。例如,你的应用程序可能存在需Servlet处理的HTTP请求,JMS请求,以及JDBC连接池。在这种情况下,我们就需要用于servlet 引擎的线程池。也需要一个JMS和JDBC组件的连接池。 此时,需要做的一件事情是将它们全部看作独立的线程池。这意味着我们需要随着服务时间累计到达率。用利特尔法则(Little&s law)来累计分析系统,从而获得线程总数。接下来就是在不同线程组中进行总数划分。划分逻辑会使用一些策略,上述策略很可能受性能需求的影响。一种策略是基于硬件的个性化要求进行线程池大小平衡。 但是,可能给予WEB客户端的优先级高于JMS请求是重要的,因此我们需要在这个思路上平衡线程池大小。当然在重新权衡时,我们需要考虑不同硬件要求来调整每个线程池的大小。
另一个考虑是这个法则更关注于系统中的平均请求数。基于很多原因,我们可能先知道90%的队列长度。使用这个值将让我们有更大空间来处理到达率的自然波动。考虑到该数字会更复杂一些,更可行的是我们在平均值顶部增加20%的缓冲。这样做时,需要确保我们有足够容量处理大量线程。例如,在我们8个线程的实验中,CPU利用率已经到了极限,再增加更多线程很可能导致性能开始下降。最后,核心模块在管理线程时要比线程池有效的多。所以当我们猜测增加线程超过8个不一定是有效时,测算可以告诉我们确实需要为潜在可能超负荷的系统增加更多容量了。换句话说,超负荷运行(如压力测试)来看看线程数对于用户响应时间和吞吐率的影响。
合适地配置线程池并不容易,但也不是超复杂的事情。背后的数学机理还是很好理解的,也很直观,因为它们一直存在于我们日常生活中。欠缺的工作是可以得到合理选择的测算(j.u.c.ExecutorService作为参考)。因为它更有点像实验化学一样精确科学,因此得到一个合适的配置还是有点繁琐,但是花点时间进行摸索,就能够降低处理超工作负荷运行而不稳定的系统的难度。
Kirk Pepperdine是一位独立顾问,专业从事Java性能调优工作。另外,她还为世界范围享有盛誉的性能调优研讨会发表文章。研讨会提出了性能调优方法学,该方法学已经提高了团队在Java性能疑难问题解决上的效率。作为2006年Java冠军,Kirk 已经写了为很多出版物写了关于性能的文章,也在很多会议&&如Devoxx JavaONE&&发表演讲。她帮助成立了网站,那是一个性能调优资源的知名站点。
查看原文链接:
感谢对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至。也欢迎大家通过新浪微博()或者腾讯微博()关注我们,并与我们的编辑和其他读者朋友交流。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
gitHub帐号做个任务,30元,支付宝交易,谢谢帮忙
Re: gitHub帐号做个任务,30元,支付宝交易,谢谢帮忙
Huang Michael
Re: gitHub帐号做个任务,30元,支付宝交易,谢谢帮忙
Huang Michael
如何下载代码
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
通过个性化定制的新闻邮件、RSS Feeds和InfoQ业界邮件通知,保持您对感兴趣的社区内容的时刻关注。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?所有池连接均在使用,并且达到了最大池大小。按这样说,只要我链接的是同一个,应该连接池中都只会有一个连接,可是我用sql&server&profiler跟踪了下事件,发现还是在某些时候创建了新的链接(SPID不同),链接都一样不是应该还是用原先池中的连接吗,在我进行大批量数据循环插入的时候就提示连接池已满,目前我只把max&pool&size设置成了15。
一定是数据库操作&sql的执行效果过低导致的连接池大小调优 - ImportNew
| 分类: ,
| 标签: ,
我之前写过和为什么两篇文章。这篇文章将讨论如何使用为你的连接池找到合适的大小。
了解你的连接池
第一步是了解你的连接池设置,我目前开发的程序使用XA事务, 因此我使用, 它自带连接池解决方案。
根据 我们需要使用以下配置项:
minPoolSize: 连接池中保留的最小连接数。
maxPoolSize: 连接池中保留的最大连接数。
maxIdleTime: 最大空闲时间。
acquisitionTimeout: 请求超时时间。30秒的默认值远远超出了我们的。
配置 Flexy Pool
自带一个默认的度量指标设置,它建立在之上并提供两种报告机制:
一个企业级的系统必须使用中央监控工具,比如 和 。而通过 使用多种报告机制是相当容易的。我们的示例将导出报告到CSV文件,你可以。
初始化设置
我们把maxOverflow和retryAttempts的值设置得足够大,让找到合适的连接池大小:
minPoolSize
连接池启动时最小连接数为0
maxPoolSize
连接池启动时最大连接数为1
acquisitionTimeout
一个连接请求的超时时间为1秒
maxOverflow
最大连接数能增长到10 (初始的 maxPoolSize + maxOverflow)
retryAttempts
如果连接池中保留的最大连接数为10并且没有可用的连接, 一个连接请求将会重试30次.
度量指标耗时
我们的程序是一个批量处理器,通过大数据可以得到以下性能指标:
1. concurrentConnectionCount
2. concurrentConnectionRequestCount
3. maxPoolSizeHistogram
4. connectionAcquireMillis
5. retryAttemptsHistogram
6. overallConnectionAcquireMillis
7. connectionLeaseMillis
在分析了各项指标之后,我们可以得到以下结论:
最大连接数应该是8。
对于这个最大连接数重试次数为0。
在连接池保留的最大连接数达到最大值以后,获取连接的时间趋于稳定。
当租约时间达到顶峰50秒的时候,连接数从7增长到8,因此降低租约时间可以帮助我们减少连接数。
如果数据库最大连接数是100,那我们可以并发运行12个程序。
假设我们需要运行19个程序而不是12个,这意味着连接数最多是5。降低连接数将会增加连接请求争用和潜在的重试次数。
这次我们把maxOverflow改为4,其它设置不变:
maxOverflow
最大连接数能增长到10 (初始的 maxPoolSize + maxOverflow)
度量指标重载
以下是新的度量指标:
1. concurrentConnectionCount
2. concurrentConnectionRequestCount
3. maxPoolSizeHistogram
4. connectionAcquireMillis
5. retryAttemptsHistogram
6. overallConnectionAcquireMillis
7. connectionLeaseMillis
分析这些指标,我们可以得出结论:
连接池保留的最大连接数为5时,重试连接次数不会超过3。
从整体连接获取时间的变化可以反映出重试次数变多了。
连接的租约时间峰值没多大变化,即便这次它大约是35秒。
即便有意外情况发生,Flexy Pool 提供的故障转移机制也有助于连接池调整优化。
当重试次数达到阀值时就会触发警报,让我们能够尽快介入。
参考: 摘自
Vlad Mihalcea 的。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
(新浪微博:)
为什么我导出的jar包,放到lib/junit目录下之后,我使用jmeter也添加junit req...
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 写了文章?看干货?去头条!
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 活跃 &#038; 专业的翻译小组
&#8211; 国内外的精选博客文章
&#8211; UI,网页,交互和用户体验
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Android技术分享
&#8211; 专注iOS技术分享
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2016 ImportNew连接池的大小怎一般是多少_百度知道
连接池的大小怎一般是多少
我有更好的答案
超过了这个连接数,就排在队列中等候,再有请求时最大连接数默认5个
其他类似问题
为您推荐:
连接池的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 连接池大小 的文章

 

随机推荐