关乎性能的思考

        现在工程师们越发的喜欢谈性能(CPU, memery, IO, container, middleware等),性能调优似乎也成为软件行业基础架构师越来越倚重的技艺之一。通常情况下,性能shooting也无外乎分为几个过程。其一,performance diagnostic & bottleneck positioning,这一步往往是关键,当然手法也是千奇百怪,这里不做赘述。第二,performance tuning,真正的调优过程是一个很Galileo,很Continuous的事情,当然也有一些模型,规则可以遵守。正如大伙疾呼:编码是一种艺术。在这,允许我呐喊一下:调优更是一门艺术。不过这门艺术要求还是有点高的,你不仅要有扎实的硬件基本知识,还要对诸多软件工作模式有一探到底的精气神。这里我们不谈性能调优如何艺术,更多的是想和大家分享一些性能调优后的思考(试图去完善一本性能调优沉思录)。思考过后,我们可以尝试着问问自己能不能做到性能架构,性能编码?注意,这里的性能架构,性能编码是自己发明的一个词汇,说的直白点,就是将性能更早的引入软件生命周期中来,别忘了,银行家算法是避免死锁的有效策略~
        那么,现在步入正题。首先我想分享的是使用Jmeter做DBCP的调优。调优的初衷很简单,提高TPS,同时减少数据库灾难带来的连接池exhaust(提高可用性)。第一个调优目标,是个很业务的事情,需要根据你的业务场景进行调整,策略上最值得注意的是maxIdle和minIdle两个参数,类似Java的-Xmx和-Xms的设置。剩下的一些参数调整,个人觉得没什么借鉴意义,所以就不赘述了,毕竟这是一件很业务的事情。再看另一个目标,这里我主要想说的是removeAbandoned和removeAbandonedTimeout。从软件的健壮性来讲,边界值问题尤为重要。在资源获取型编码过程中,最好的体现就是超时时间的设置,这是个很经验,很统计概率的事情。对样本空间进行充分取样,一定可以得出该样本空间样本点的均值,当然还有均方差。后者更多的在关注样本点与平均值的偏离程度。仔细体会一下Jmeter的90%
Line性能指标(这只是一个很简单的数学场景,后面有机会和大家分享一篇性能调优中的数学之美的博文)。好了,话题收敛一下,我来解释一下removeAbandonedTimeout的重要性:当connection idle时间超越这个数值时, AbandonedObjectPool会在borrowObject和returnObject时会先进行连接的有效性判断。很好理解,在借出对象时,需要判断该对象是否处于活跃状态(不满足removeAbandoned条件则归还,满足需要看超时时间,然后…);归还时的判断原则大致类同,这个很容易想到。代码如下:

/**
     * Get a db connection from the pool.
     *
     * If removeAbandoned=true, recovers db connections which
     * have been idle > removeAbandonedTimeout and
     * getNumActive() > getMaxActive() - 3 and
     * getNumIdle() < 2
     *
     * @return Object jdbc Connection
     * @throws Exception if an exception occurs retrieving a
     * connection from the pool
     */
    public Object borrowObject() throws Exception {
        if (config != null
                && config.getRemoveAbandoned()
                && (getNumIdle() < 2)
                && (getNumActive() > getMaxActive() - 3) ) {
            removeAbandoned();
        }
        Object obj = super.borrowObject();
        if (obj instanceof AbandonedTrace) {
            ((AbandonedTrace) obj).setStackTrace();
        }
        if (obj != null && config != null && config.getRemoveAbandoned()) {
            synchronized (trace) {
                trace.add(obj);
            }
        }
        return obj;
    }
/**
     * Return a db connection to the pool.
     *
     * @param obj db Connection to return
     * @throws Exception if an exception occurs returning the connection
     * to the pool
     */
    public void returnObject(Object obj) throws Exception {
        if (config != null && config.getRemoveAbandoned()) {
            synchronized (trace) {
                boolean foundObject = trace.remove(obj);
                if (!foundObject) {
                    return; // This connection has already been invalidated.  Stop now.
                }
            }
        }
        super.returnObject(obj);
    }

        通过分析,压测,调整参数验证,我们达到了优化目标(主要是基于以上参数的调整)。而后,我们需要认真反思一下:在拿到一款开源软件并成功run起来,进入到production环境前,是不是需要做点啥?每依赖一个新Jar包,就压测一通,是不是很没章法,显得?能不能理论指导实践一下呢?我的回答是当然可以,但需要仔细研读一下关乎性能的相关参数说明。当然,哪些会成为你着重关注的性能参数,这又是一个很经验的事情。再举个例子,之前做过几个Connection调优的事情,问题定位到最后,发现两边的Connection
timeout设置的不具备“包容性”。具体来说,在Tomcat的AJP connector和apache的mod_jk connector pipe对接时,处于请求响应数据流向的AJP connector端的timeout是不是可以大于等于mod_Jk counterpart呢?试想一下,倘若前者过小,当连接数大于connection_pool_minsize,并且connection_pool_timeout 超时,mod_jk会主动断开连接。而Tomcat 这边只要到了connectionTimeout超时时间,就会立即放弃连接。这就导致了mod_jk
继续持有连接,而Tomcat这边却放弃了这条连接。后果很严重吧(不作不死的Timewait问题)?为了更形象点,我还是把关键配置项摘录下来吧:
workers.properties:

worker.node1.connection_pool_minsize=25
worker.node1.connection_pool_timeout=600

server.xml :

<Connector port="8009" address="${jboss.bind.address}" protocol="AJP/1.3" emptySessionPath="true" enableLookups="false" redirectPort="8443" URIEncoding="UTF-8" backlog="256" maxThreads="250" connectionTimeout="600000"/>

         Hmm,既然已经注意到了这点,我们就可以把Tomcat的connectionTimeout调得比较大,让它完全包容mod_Jk counterpart,又或者把mod_jk的connection_pool_minsize 设成0,再或者在mod_jk中设置worker.node1.prepost_timeout=10000 ,通过断开死连接的方式,都是可以解决这个问题的。写到这,忽然想起之前封装的那个高性能的HttpClient。为什么我敢“吹牛”它是高性能呢?原因很简单,Apache的性能参数之前我们已经进行了调优(通过分析日志统计出连续HTTP请求出现的次数、间隔时间、访问量,
以确定 MaxKeepAliveRequests 和 KeepAliveTimeout 的值。说到这里,我有必要提醒大家注意一下Timeout和KeepAliveTimeout的区别,用两段官方的解释说明一下吧,个人觉得很贴切:

The TimeOut directive currently defines the amount of time Apache will wait for three things: 

1. The total amount of time it takes to receive a GET request. 
2. The amount of time between receipt of TCP packets on a POST or PUT request. 
3. The amount of time between ACKs on transmissions of TCP packets in responses. 

The number of seconds Apache will wait for a subsequent request before closing the connection.Once a request has been received, the timeout value specified by the Timeout directive applies. 

),那么我封装HttpClient的时候,只需要对接apache的MPM参数(具体可参看:http://blog.csdn.net/fengjia10/article/details/7315279),那么在设计,编码阶段就可以解决大部分性能问题,剩下的就是根据业务场景稍作调优即可。

小结: 

通过这篇博客,我想说的是,作为职业架构师,我们不仅要读的通源码,玩得起perf tool(分析问题,解决问题),更需要的是将你的优化意识尽可能早的引入到软件的研发周期中(根据以往的经验,过早考虑性能,也可能会导致代码晦涩难懂。建议在设计中作为非功能需求考量,并在代码的优化阶段(也可能是提测后)实施性能调优),即架构设计,甚至是基础代码的编写过程中。尽可能的运用数学模型去验证你的性能参数选择。请牢牢记住:意识永远比技术更重要。

参考资料:

1. http://commons.apache.org/dbcp/configuration.html

2. http://software.intel.com/zh-cn/articles/book-Multicore-Multithread-Technology_tuning_cycle/

时间: 2025-01-27 16:55:59

关乎性能的思考的相关文章

陈皓:由12306.cn引发的网站性能技术思考

中介交易 SEO诊断 淘宝客 云主机 技术大厅 伴随着十一长假的来临,大家对于铁道部12306的讨论又多了起来.这篇文章(原文)从12306网站延展到网站性能的诸多讨论,对于创业者与技术爱好者有很强的借鉴意义.本文作者陈皓(weibo)有14年软件开发相关工作经验,8年以上项目和团队管理经验. 12306.cn网站挂了,被全国人民骂了.我这两天也在思考这个事,我想以这个事来粗略地和大家讨论一下网站性能的问题.因为仓促,而且完全基于本人有限的经验和了解.只讨论性能问题,不讨论那些UI,用户体验,或

按分类统计商品总数的性能优化思考

如上图,在很多购物类商城系统中经常能看到类似的产品分类列表,今天市场部的同志们要求每个分类后要显示该类的产品总数,并且没有产品的分类不用显示.公司这个项目中的分类有近1000种(并且是无限级分类的树型结构),如果按常规统计方法,每个分类ID都去count一下(同时考虑到每个分类的下级子分类产品数),这样的处理效率肯定很低的.   想了个办法从二个层面优化: 1.数据库层面 创建一个临时表,用游标把产品总数分类事先统计好,一次性在数据库中完成,避免ASPX页面中的多次查询请求. -- ======

网站标题关乎营销再思考

摘要: 如果说一个网站的成功取决于内容质量,那么好的标题无异于点睛之笔.对于普通用户而言,在不知情的时候多半通过搜索引擎检索网站,而呈现在用户面前的首先就是网站的标题.所 如果说一个网站的成功取决于内容质量,那么好的标题无异于点睛之笔.对于普通用户而言,在不知情的时候多半通过搜索引擎检索网站,而呈现在用户面前的首先就是网站的标题.所以,懂得搜索引擎营销之人,不只会通过竞价提升排名,而且懂得如何通过富有创意的广告标题猎取用户的注意力.毕竟,在用户尚未打开任何一个网站之前,注意力就是营销力,就可以获

成败就在字词间 网站标题关乎营销再思考

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 如果说一个网站的成功取决于内容质量,那么好的标题无异于点睛之笔.对于普通用户而言,在不知情的时候多半通过搜索引擎检索网站,而呈现在用户面前的首先就是网站的标题.所以,懂得搜索引擎营销之人,不只会通过竞价提升排名,而且懂得如何通过富有创意的广告标题猎取用户的注意力.毕竟,在用户尚未打开任何一个网站之前,注意力就是营销力,就可以获得更多的营销机会

轻量函数式 JavaScript:八、列表操作

你在前一章闭包/对象的兔子洞中玩儿的开心吗?欢迎回来! 如果你能做很赞的事情,那就反复做. 我们在本书先前的部分已经看到了对一些工具的简要引用,现在我们要非常仔细地看看它们,它们是 map(..).filter(..).和 reduce(..).在 JavaScript 中,这些工具经常作为数组(也就是"列表")原型上的方法使用,所以我们很自然地称它们为数组或列表操作. 在我们讨论具体的数组方法之前,我们要在概念上检视一下这些操作是用来做什么的.在这一章中有两件同等重要的事情:理解列表

Hybrid移动应用:用网页技术提供Native体验

  根据最近的一篇报告显示,HTML是移动应用开发人员使用最多的语言,开发人员对于选择哪种网页技术考虑的最主要因素,是代码的跨平台便携性和开发的低成本性.我们常常听说,hybrid app使用起来非常慢,而且设计也很糟糕,让我们看看是否有可能又有原生应用的形,又有我们习惯使用的感. 这篇文章会提供很多关于如何构建良好的hybrid移动应用的线索.代码片段和经验.我将会大致介绍一下hybrid移动应用的开发,包括它的优点和缺点.然后,我会分享一下过去两年我在开发Hojoki和CatchApp时积累

怎么挑选固态硬盘

  怎么挑选固态硬盘? 打开某大电商网站的SSD固态硬盘陈列页面,目前可以看到40种不同的品牌.这可能会让很多人困惑,怎么会有这么多牌子?要知道,机械硬盘市场经过残酷竞争的洗礼,目前就剩下几个著名品牌:希捷.西部数据(西数).东芝.日立,其中日立还被西数收购了.机械硬盘生产制造的技术非常复杂,条件苛刻,能做出有竞争力的产品的公司,就那么几家.而SSD固态硬盘不同,它还处于蓬勃发展中,远未达到成熟的阶段.它的主要原件就是主控和闪存芯片.主控芯片类似于CPU,有多家公司在提供产品,各具特色,性能不一

cpu散热器哪种好

  在DIY电脑领域,很多玩家在装机的时候,注意力往往主要集中在关乎电脑性能的CPU,显卡,主板,内存,硬盘等核心硬件之上,对机箱电源,散热器等硬件往往不太在乎.也正因为如此,一些朋友组装的电脑往往配备的是一些劣质散热器,山寨机箱电源等等,今后在使用的时候,就很容易出现各种散热不良,电脑无故重启,甚至蓝屏等问题. 其实,在DIY电脑中,木桶效应是尤为需要注意的,忽视了散热器.电源等硬件,可能会导致整个主机平台的性能.稳定性乃至寿命,都产生影响.今天,电脑百事网小编主要分享一下电脑CPU散热器的选

并发编程10-性能和可伸缩性

性能的思考 使用多线程也会引入一些性能的开销,比如线程协调,上下文切换,线程创建和消亡. 当使用过度的时候这些开销可能超过对吞吐量响应和提高计算能力带来的好处. 可伸缩性就是可以通过增加计算资源(CPU,内存)来提供程序的吞吐量或者性能. 程序的串行化代码影响程序的性能,使用多线程来优化性能时,串行部分无法优化. 上下文切换,比如哪个等待,哪个执行,会损害性能 竞争性的锁会损失性能和可伸缩性. 减少锁的竞争 通常可以: - 减少持有锁的时间 - 减少请求锁的频率 - 用协调机制代替独占锁 缩小锁