﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-BlueDavy之技术Blog-随笔分类-Internet</title><link>http://www.blogjava.net/BlueDavy/category/32839.html</link><description>理论不懂就实践，实践不会就学理论！</description><language>zh-cn</language><lastBuildDate>Wed, 03 Sep 2008 17:33:24 GMT</lastBuildDate><pubDate>Wed, 03 Sep 2008 17:33:24 GMT</pubDate><ttl>60</ttl><item><title>大型网站架构演变和知识体系</title><link>http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 03 Sep 2008 11:12:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/226749.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/226749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/226749.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 之前也有一些介绍大型网站架构演变的文章，例如LiveJournal的、ebay的，都是非常值得参考的，不过感觉他们讲的更多的是每次演变的结果，而没有很详细的讲为什么需要做这样的演变，再加上近来感觉有不少同学都很难明白为什么一个网站需要那么复杂的技术，于是有了写这篇文章的想法，在这篇文章中 将阐述一个普通的网站发展成大型网站过程中的一种较为典型的架构演变历程和所需掌握的知识体系，希望能给想从事互联网行业的同学一点初步的概念，:)，文中的不对之处也请各位多给点建议，让本文真正起到抛砖引玉的效果。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/226749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-09-03 19:12 <a href="http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>外行人谈压力测试</title><link>http://www.blogjava.net/BlueDavy/archive/2008/07/25/217514.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Fri, 25 Jul 2008 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/07/25/217514.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/217514.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/07/25/217514.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/217514.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/217514.html</trackback:ping><description><![CDATA[不是专职做压力测试这行当的，只能是以自己的经验来以外行人的眼光来说说压力测试，压力测试并不仅仅是个压力测试的过程，而是一个相当系统和复杂的工程，我认为压力测试是为了让系统达到所期望的运行效果以及承受所期望的压力，这也就要求压力测试应该帮助性能调优团队，为其提供一定程度的指导，在这里我不将压力测试和性能调优分的那么清楚了，在我看来，压力测试过程包括了：明确压力测试的目标、制定压力测试方案、进行压力测试、分析压力测试结果、寻找瓶颈并进行调优以达到目标，在这篇blog中来细看下这几个过程以及常用的方法。<br />
<strong>明确压力测试的目标</strong><br />
通常来说（注意是通常），压力测试的目标有这么几点：<br />
1、评测系统是否满足压力支撑的要求<br />
&nbsp;&nbsp; 要评测系统是否满足压力支撑的要求，同样要做的就是需要明确定义系统需要支撑多大的压力，例如：<br />
&nbsp;&nbsp; 机器的配置：CPU、内存、硬盘、etc.<br />
&nbsp;&nbsp; 网络条件：100M<br />
&nbsp;&nbsp; 操作系统：Linux core: 2.6<br />
&nbsp;&nbsp; 当并发数为10用户时，系统应能在20ms内响应完毕（这个时候的TPS为500），系统的load需在2以下；当并发数为100用户时，系统应能在50ms内响应完毕（这个时候的TPS为2000），系统的load需在4以下；当并发数为200用户时，系统应能在80ms内响应完毕（这个时候的TPS为2500），允许其中有千分之一的出错率，系统的load需在6以下，在压力测试的过程中，只要其中的任何指标未达到，均可判定系统尚未达到压力的目标。<br />
&nbsp;&nbsp; 实际的压力测试的这个指标会比我这里举的例子复杂很多，例如还需要考虑网络流量、内存消耗、IOPS、连接数等等。<br />
&nbsp;&nbsp; 这里面压力测试隐藏的目标是为容量规划提供一定的指导，例如目前的系统在某种配置的情况下单台机器能承受的最大并发数为100用户，那么如果系统的高峰压力是1000的话，如果系统支撑无损水平扩展的话就意味着需要10台这类配置的机器，这一步同样是经过测试的。<br />
2、预估系统上线运行的状况&nbsp; <br />
&nbsp;&nbsp; 毕竟通常压力测试环境和线上的环境是会有很大的不同的，压力、数据量、硬件环境等，基本上只能是根据线下的环境的情况进行一定比例的对比后计算来预估，这里面很重要的是要预估系统上线后正常情况下的表现状况、一定的增长比率后的运行状况以及风险点（例如当并发用户数增长到多少时、系统load到多少时可能会出现问题）。<br />
&nbsp;&nbsp; 这一个目标我觉得非常难达到，但随着经验，我相信是可以做到的，如果能做到这种效果的话是会有很大的帮助的。<br />
以上这个两个目标基本是压力测试都要达到或希望达到的，而具体有可能会因为系统的业务的具体情况会制定其他不同的目标。<br />
<strong>制定压力测试方案</strong><br />
这步是压力测试整个过程中最难的步骤之一，为了能够测试出系统是否符合压力支撑的要求以及评估上线的表现，通常我们会希望搭建出和生产环境完全相同的环境，但这就是最麻烦的一点了，基本上是不太可能的，因此通常能采取的方法会是：<br />
1、做等比例的缩放<br />
&nbsp;&nbsp; 按照生产环境的情况做一定比例的缩放，例如生产环境的数据量为1亿条，那么测试环境等比缩放到5000w条，生产环境的处理速度的情况...；<br />
2、更差环境、更高压力的测试<br />
&nbsp;&nbsp; 采取比生产环境更差的机器配置、网络环境来进行测试，例如ebay的要求是能够承受10x的压力。<br />
3、仿真测试<br />
&nbsp;&nbsp; 据资深人士而言，仿真测试要做到基本是不太可能的，仿真测试首先要求的是收集到生产环境中的运行状态的数据，然后在测试环境中编写程序来做到模拟生产环境运行的效果，这个难度基本是非常高的。<br />
我自己现在做压力测试更多采取的做法是以上三种方法的合集。<br />
在确定了测试方法后，就基本可以确定压力测试的环境了，环境确定好后需要做的是压力测试的案例或场景了，在压力测试的案例中需要涵盖正常场景以及异常的场景，正常场景是非常容易做出来的，只是需要根据生产环境收集的数据（例如不同级别的用户比例通常是7:2:1）或预估的数据来搭建相应的测试案例，异常场景则是比较复杂的，需要考虑很多的因素，例如数据库出现异常、网络出现异常等，这里我觉得通常的做法是画出正常场景的处理流程，然后划分交互边界的信任边界，对于所有的第三方交互都认为是不可信任，例如不能信任调用数据库是一定会快的，或一定会成功的，在异常场景中应涵盖这些信任边界的异常状况的测试，这些对于高可用性的系统而言是非常重要的，几个9的成败就在此了，^_^，当然，高可用性又是个更复杂的话题，不在这里讲。<br />
在压力测试方案中还需确定的是考评的指标，通过会包括：tps、系统load等等。<br />
<strong>进行压力测试</strong><br />
相对来讲，在有了压力测试方案后，这一步并不是什么太复杂的事情，只是需要选择一个和压力测试方案比较符合的工具来执行，例如jmeter、loadrunner等，当然，这些工具相对来说也是比较复杂的，而且之间的差距也是比较大的，至少目前来看，jmeter和loadrunner的差距还是不小的，尤其是需要进行高压力的测试时。<br />
<strong>分析压力测试结果</strong><br />
这步同样是压力测试中很难的一步，在这一步需要做出的根据压力测试的结果分析出系统的具体表现情况，判定系统是否能够满足压力指标。<br />
以loadrunner产生的分析结果图而言，通常需要分析以下图：<br />
1、Total Transactions per Second<br />
&nbsp;&nbsp; 这张图中显示了系统在进行压力测试过程的TPS的变化情况，从这张图中我们可以看到系统的TPS的情况，通常来讲，随着用户数的增加，TPS应该是呈一定比率的增长的，等增长到一定程度后会达到瓶颈，甚至开始下降，这也是TPS的瓶颈值了，这张图可以帮助我们评估系统的TPS是否符合要求。<br />
&nbsp;&nbsp; 另外，在这张图中，我们可以看到系统从什么时候开始出现出错的transactions，从而判断出错率是否在可接受的范围。<br />
2、Transaction Response Time Under Load<br />
&nbsp;&nbsp; 这张图非常的重要，借助这张图我们可以分析随着用户数增加的情况下，系统的劣化状况，最佳状况当然是一条直线，但这基本是不可能的，毕竟资源是有限的，需要判断的是劣化的程度是否为可接受范畴。<br />
&nbsp;&nbsp; 另外就是需要关注数据中90%的用户的响应时间的状况，如果少量用户响应慢是可接受的话，那么有可能在之上指标不达标的情况下仍然满足了压力指标。<br />
3、Unix Resources<br />
&nbsp;&nbsp; 这张系统load图自然是非常的重要，借助这张图大致可以判断系统随着用户数的增长消耗的资源的变化情况，这对于调优以及容量规划而言是很重要的，但还是得取决于应用本身，:)。<br />
loadrunner还提供了其他方面很多的图，可以根据考评的要求来自行进行分析。<br />
<strong>寻找瓶颈并进行调优以达到目标</strong><br />
这步不属于压力测试范畴，但还是在这里稍微讲讲，毕竟压力测试结束后如果系统没达标的话就必须进行这步了。<br />
寻找瓶颈，这自然是非常难的事了，通常系统达不到要求的状况都会是随着用户的增长，响应时间劣化的过于厉害，在这样的情况下首先得观察系统硬件资源的变化情况，如果是硬件资源耗尽的话，需要查查为什么资源被耗尽，假设最后判断确实需要耗费这么多的硬件资源的话，也许需要考虑增加硬件资源或是水平扩展，否则的话可能需要从软件层面相应的优化系统了，这样的话可以进入下一步了。<br />
如果不是硬件资源的限制的话，得在系统中从头到尾设置时间跟踪filter，从而判断响应时间劣化的原因，看看是系统中哪些步骤造成的，这个是细致活了，有可能要查非常久。<br />
其实这里说的还是相当的简单了，在寻找瓶颈的过程中是个非常繁琐的过程，需要不断的尝试，硬件的增加、OS的调优、jvm的调优以及软件系统本身的调优等等，这些很多时候需要的是经验，因此某知名人士曾经说过如何寻找瓶颈和调优，其中依靠的一点就是直觉，^_^。<br />
当然，在寻找瓶颈的过程中，可以借助os的工具、java的工具（例如gc打印、jprofiler等）来进行查找。<br />
（ps: 不过感觉很多情况下都是应用本身造成的性能瓶颈，在写程序时稍不注意用错一个数据结构都有可能会导致比较大的问题，所以我现在查找瓶颈的时候更多的还是先从软件本身下手，只是软件性能要做到提升通常来付出较大的代价，这个时候需要权衡）<br />
调优基本上要求对硬件、OS、JDK、数据库甚至软件的实现方式等都要有非常深入的理解，至少要能做到判断出瓶颈因素，然后找相应领域的专家来解决，因此要求是非常高的。<br />
关于性能调优的知识体系这里有篇不错的文章：<br />
http://www.cnblogs.com/jackei/archive/2008/06/27/1231307.html<br />
<br />
话题太大了，写到最后发现基本上还是有些泛泛而谈了，后面会针对这里的每一步来做更为细致的实例的讲述吧，不过毕竟是外行人，肯定有很多不对的地方，欢迎大家指正、拍砖。<br />
<br />
<img src ="http://www.blogjava.net/BlueDavy/aggbug/217514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-07-25 17:40 <a href="http://www.blogjava.net/BlueDavy/archive/2008/07/25/217514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】构建可扩展的Java EE应用（二）</title><link>http://www.blogjava.net/BlueDavy/archive/2008/07/10/213988.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 10 Jul 2008 07:42:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/07/10/213988.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/213988.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/07/10/213988.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/213988.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/213988.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这篇文章的第二部分在昨天也发布出来了，于是抓紧时间把它给翻译了。在这篇文章的第一部分中，作者结合自己的经验对如何构建具备良好的垂直扩展能力的Java EE应用做了讲解，在这第二部分的文章中，作者则对如何构建具备良好水平扩展能力的Java EE应用来进行了详细的讲述，常见的session复制问题，水平扩展中经常需要涉及的分布式文件系统、分布式缓存、分布式并行计算，全文读下来，作者基本指出了构建可扩展的Java EE应用需要了解的知识体系（如需深入的话还有必要进一步的学习，例如集群技术、通讯协议、线程、并发等）和平时实践中的一些注意事项，应该说是篇十分难得的好文章，值得推荐。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2008/07/10/213988.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/213988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-07-10 15:42 <a href="http://www.blogjava.net/BlueDavy/archive/2008/07/10/213988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】构建可扩展的Java EE应用（一）</title><link>http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Mon, 07 Jul 2008 15:15:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/213179.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/213179.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/213179.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这是一篇从TheServerSide上翻译过来的文章，很自豪这篇这么好的文章是一个中国人（从作者名字上猜想应该是中国人吧，:)）写的，原文地址为：http://www.theserverside.com/tt/articles/article.tss?l=ScalingYourJavaEEApplications，可以说，这篇文章写的是非常的不错的，这是文章的第一部分，探讨了如何构建可垂直扩展的Java EE应用，文中谈论到的让所编写的Java EE应用具备垂直扩展能力的几个关键要素，例如热锁问题、尽可能的缩短同步块、不要在static方法上加锁、多使用Atomic包、jvm内存不能设置的太大等，文中除了列了这几个关键要素外，还详细的解释了为什么不能做以及如何避免出现这样的现象，可以很明显的看出作者在这些方面是具备了非常丰富的经验的，因此这篇文章不仅仅讲述了可扩展性理论方面的知识，同时也很好的从实战角度进行了分析，之后我也会结合这篇文章来说说自己曾经碰到的垂直扩展场景的反例，同时也很期待这篇文章的第二部分，第二部分将探讨如何构建可水平扩展的Java EE应用，翻译的不好的地方还请大家多&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/213179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-07-07 23:15 <a href="http://www.blogjava.net/BlueDavy/archive/2008/07/07/213179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP的Request session的有效时间应合理设置</title><link>http://www.blogjava.net/BlueDavy/archive/2008/07/03/212370.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 03 Jul 2008 08:24:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/07/03/212370.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/212370.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/07/03/212370.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/212370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/212370.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 之前写了个简单的jsp做压力测试，没想到出现的一个问题是当压力比较大的情况，运行比较久的话会出现一个现象，就是jvm的内存几乎被耗尽，用 jprofiler查看会发现是有一个ConcurrentHashMap对象的内存一直在增长，而且没有释放的迹象，随后进入Debug模式，跟踪查找都有谁new了ConcurrentHashMap，因为测试场景中是个非常简单的jsp页面，发现只有jsp的Request session会创建这个ConcurrentHashMap，很久没写jsp了，猜测是request session的默认超时时间太长，所以导致高压力下(200并发，总共连续访问50万次，jvm内存1G)会出现内存一直没有回收的问题，后来打印了一下request session的默认超时(AS是jboss 4.2.2)，是半小时，如果这样的话确实是会有造成上面内存一直被占用的现象。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2008/07/03/212370.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/212370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-07-03 16:24 <a href="http://www.blogjava.net/BlueDavy/archive/2008/07/03/212370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>性能调优概述</title><link>http://www.blogjava.net/BlueDavy/archive/2008/06/29/211558.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sun, 29 Jun 2008 15:37:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2008/06/29/211558.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/211558.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2008/06/29/211558.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/211558.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/211558.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 性能调优无疑是个庞大的话题，也是很多项目中非常重要的一环，性能调优的难做是众所周知的，毕竟性能调优涵盖的面实在是太多了，在这篇blog中我们蜻蜓点水般的来看看性能调优这项庞大的工程都有些什么过程，同时也看看这些过程中常见的一些做法。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2008/06/29/211558.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/211558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2008-06-29 23:37 <a href="http://www.blogjava.net/BlueDavy/archive/2008/06/29/211558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>