﻿<?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-小菜毛毛技术分享-随笔分类-性能优化</title><link>http://www.blogjava.net/caizh2009/category/43909.html</link><description>与大家共同成长</description><language>zh-cn</language><lastBuildDate>Thu, 26 Aug 2010 16:35:14 GMT</lastBuildDate><pubDate>Thu, 26 Aug 2010 16:35:14 GMT</pubDate><ttl>60</ttl><item><title>关于Java性能监控</title><link>http://www.blogjava.net/caizh2009/archive/2010/08/25/329857.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Wed, 25 Aug 2010 02:04:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/08/25/329857.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/329857.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/08/25/329857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/329857.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/329857.html</trackback:ping><description><![CDATA[<p>责怪糟糕的代码（或不良代码对象）并不能帮助您发现瓶颈，提高 Java&#8482; 应用程序速度，猜测也不能帮您解决。Ted Neward 引导您关注 Java 性能监控工具，从5 个技巧开始，使用Java 5 的内置分析器JConsole 收集和分析性能数据。</p>
<p>当应用程序性能受到损害时，大多数开发人员都惊慌失措，这在情理之中。跟踪 Java 应用程序瓶颈来源一直以来都是很麻烦的，因为 Java 虚拟机有黑盒效应，而且 Java 平台分析工具一贯就有缺陷。</p>
<p>然而，随着 Java 5 中 JConsole 的引入，一切都发生了改变。JConsole 是一个内置 Java
性能分析器，可以从命令行或在 GUI shell
中运行。它不是完美的，但是当尖头老板来问你关于性能的问题时，用它来应对还是绰绰有余的——这比查询 Papa Google 要好得多。</p>
<p>在本期 5 件事 系列中，我将向您展示 5 个方法，使您可以轻松地使用 JConsole（或者，它更高端的 &#8220;近亲&#8221; VisualVM ）来监控 Java 应用程序性能和跟踪 Java 中的代码。</p>
<p><strong>1. JDK 附带分析器</strong></p>
<p>许多开发人员没有意识到从 Java 5 开始 JDK 中包含了一个分析器。JConsole（或者 Java
平台最新版本，VisualVM）是一个内置分析器，它同 Java 编译器一样容易启动。如果是从命令行启动，使 JDK 在 PATH 上，运行
jconsole 即可。如果从 GUI shell 启动，找到 JDK 安装路径，打开 bin 文件夹，双击 jconsole。</p>
<p>当分析工具弹出时（取决于正在运行的 Java 版本以及正在运行的 Java 程序数量），可能会出现一个对话框，要求输入一个进程的 URL 来连接，也可能列出许多不同的本地 Java 进程（有时包含 JConsole 进程本身）来连接。</p>
<p><strong>使用 JConsole 进行工作</strong></p>
<p>在 Java 5 中，Java 进程并不是被设置为默认分析的，而是通过一个命令行参数 —
-Dcom.sun.management.jmxremote — 在启动时告诉 Java 5 VM 打开连接，以便分析器可以找到它们；当进程被
JConsole 捡起时，您只能双击它开始分析。</p>
<p>分析器有自己的开销，因此最好的办法就是花点时间来弄清是什么开销。发现 JConsole
开销最简单的办法是，首先独自运行一个应用程序，然后在分析器下运行，并测量差异。（应用程序不能太大或者太小；我最喜欢使用 JDK 附带的
SwingSet2 样本。）因此，我使用 -verbose:gc 尝试运行 SwingSet2 来查看垃圾收集清理，然后运行同一个应用程序并将
JConsole 分析器连接到它。当 JConsole 连接好了之后，一个稳定的 GC 清理流出现，否则不会出现。这就是分析器的性能开销。</p>
<p><strong>2. 远程连接进程</strong></p>
<p>因为 Web 应用程序分析工具假设通过一个套接字进行连通性分析，您只需要进行少许配置来设置 JConsole（或者是基于 JVMTI 的分析器，就这点而言），监控/分析远程运行的应用程序。</p>
<p>如果 Tomcat 运行在一个名为 &#8220;webserve&#8221; 的机器上，且 JVM 已经启动了 JMX 并监听端口 9004，从
JConsole（或者任何 JMX 客户端）连接它需要一个 JMX URL
&#8220;service:jmx:rmi:///jndi/rmi://webserver:9004/jmxrmi&#8221;。</p>
<p>基本上，要分析一个运行在远程数据中心的应用程序服务器，您所需要的仅仅是一个 JMX URL。更多关于使用 JMX 和 JConsole 远程监控和管理的信息，参见 参考资料。）</p>
<p><strong>3. 跟踪统计</strong></p>
<blockquote>
<p>JConsole 有许多对收集统计数据有用的选项卡，包括：</p>
<p>Memory：在 JVM 垃圾收集器中针对各个堆跟踪活动。</p>
<p>Threads：在目标 JVM 中检查当前线程活动。</p>
<p>Classes：观察 VM 已加载类的总数。</p>
</blockquote>
<p>这些选项卡（和相关的图表）都是由每个 Java 5 及更高版本 VM 在 JMX 服务器上注册的 JMX 对象提供的，是内置到 JVM
的。一个给定 JVM 中可用 bean 的完整清单在 MBeans
选项卡上列出，包括一些元数据和一个有限的用户界面来查看数据或执行操作。（然而，注册通知是在 JConsole 用户界面之外。）</p>
<p><strong>使用统计数据</strong></p>
<p>假设一个 Tomcat 进程死于 OutOfMemoryError。如果您想要弄清楚发生了什么，打开 JConsole，单击
Classes 选项卡，过一段时间查看一次类计数。如果数量稳定上升，您可以假设应用程序服务器或者您的代码某个地方有一个 ClassLoader
漏洞，不久之后将耗尽 PermGen 空间。如果需要更进一步的确认问题，请看 Memory 选项卡。</p>
<p><strong>4. 为离线分析创建一个堆转储</strong></p>
<p>生产环境中一切都在快速地进行着，您可能没有时间花费在您的应用程序分析器上，相反地，您可以为 Java 环境中的每个事件照一个快照保存下来过后再看。在 JConsole 中您也可以这样做，在 VisualVM 中甚至会做得更好。</p>
<p>先找到 MBeans 选项卡，在其中打开 com.sun.management 节点，接着是 HotSpotDiagnostic
节点。现在，选择 Operations，注意右边面板中的 &#8220;dumpHeap&#8221; 按钮。如果您在第一个（&#8220;字符串&#8221;）输入框中向 dumpHeap
传递一个文件名来转储，它将为整个 JVM 堆照一个快照，并将其转储到那个文件。</p>
<p>稍后，您可以使用各种不同的商业分析器来分析文件，或者使用 VisualVM 分析快照。（记住，VisualVM 是在 Java 6 中可用的，且是单独下载的。）</p>
<p><strong>5. JConsole 并不是高深莫测的</strong></p>
<p>作为一个分析器实用工具，JConsole 是极好的，但是还有更好的工具。一些分析插件附带分析器或者灵巧的用户界面，默认情况下比 JConsole 跟踪更多的数据。</p>
<p>JConsole 真正吸引人的是整个程序是用 &#8220;普通旧式 Java &#8221; 编写的，这意味着任何 Java
开发人员都可以编写这样一个实用工具。事实上，JDK 其中甚至包括如何通过创建一个插件来定制 JConsole 的示例（参见 参考资料）。建立在
NetBeans 顶部的 VisualVM 进一步延伸了插件概念。</p>
<p>如果 JConsole（或者
VisualVM，或者其他任何工具）不符合您的需求，或者不能跟踪您想要跟踪的，或者不能按照您的方式跟踪，您可以编写属于自己的工具。如果您觉得
Java 代码很麻烦，Groovy 或 JRuby 或很多其他 JVM 语言都可以帮助您更快完成。</p>
<p>您真正需要的是一个快速而粗糙（quick-and-dirty）的由 JVM 连接的命令行工具，可以以您想要的方式确切地跟踪您感兴趣的数据。</p>
<p><strong>结束语</strong></p>
<p>Java 性能监控不止于 JConsole 或 VisualVM — 在 JDK 中隐藏着一整套工具，只是大多数开发人员并不知道。 本系列
中的下一篇文章将深入探究一些实验性的命令行工具，可以帮助您挖掘更多的您所需要的性能数据。因为这些工具通常只关注特殊数据，比一个完整的分析器更小更
轻巧，所以它们的性能开销要小一些。</p>
<img src ="http://www.blogjava.net/caizh2009/aggbug/329857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-08-25 10:04 <a href="http://www.blogjava.net/caizh2009/archive/2010/08/25/329857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>weblogic如何诊断 J2EE 系统中的性能问题</title><link>http://www.blogjava.net/caizh2009/archive/2010/02/05/312097.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Fri, 05 Feb 2010 05:32:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/02/05/312097.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/312097.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/02/05/312097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/312097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/312097.html</trackback:ping><description><![CDATA[现在要求您诊断 WebLogic J2EE 应用程序中的性能问题。因为 Java 系统是如此复杂，所以诊断 WebLogic J2EE 应用程序中的性能问题就有点像诊断疑难杂症。<br />
为了正确地找到问题所在，您需要对症状有全面了解，要做好准备进行大量研究工作，最后您需要制定正确的治疗方案。本文讨论了 J2EE 应用程序性能问题的一些最常见类型和它们产生的原因，以及如何正确地诊断和消除它们的推荐指导原则。<br />
<br />
<br />
<strong>症状</strong><br />
　　WebLogic 应用程序性能问题的症状是什么？您看到的症状可以指导您在所有可能的问题中进行搜索。请准备一个笔记本并开始向人们调查。试着把对问题根本原因的推测和假设与系统行为的实际证据分离。下面是一个常见症状集的列表： 持续缓慢：应用程序一直特别慢。改变环境因素(负载、数据库连接数量)对整体响应时间的改变很小。 随着时间推进越来越慢：系统运行时间越长(负载相对均衡不变的情况下)，就变得越慢。有可能是(最后)达到了某个阈值，系统被锁定或者由于大量错误而崩溃。 随着负载增加越来越慢：每增加一个额外用户，应用程序就变得越慢。如果用户离开系统，系统就&#8220;冷却下来&#8221;，恢复正常。 零星的挂起或者异常错误：偶尔(可能由于负载或某些其它原因)，在页面无法完成或者出现追踪到异常和堆栈的错误页时，用户会看到挂起的情况。挂起的数量可能不同，但总是无法完全消除，甚至在强化 (&#8220;burn in&#8221;) 期间之后也是如此。 可以预见的锁定：首先出现一些挂起或错误，然后加速出现，直到系统完全被锁定。通常这些问题可以通过&#8220;重新启动来管理&#8221;的方式解决。 突然混乱：系统一直运行正常，相当一段时间里(可能一个小时，也可能是三天)性能都还差强人意，但是&#8220;突然某个时候，根本没有任何原因的&#8221;，系统开始出现大量错误，或者被锁定。
<p><strong>为什么问题诊断如此复杂？</strong> <span class="Smn995">软件开发网</span> <br />
　　对于 WebLogic 应用程序的某个具体应用模式来说，没有既定的公式可以用来推导出它的性能(在严格的实时工程当中，速度单调分析这类技术确实可以做这项工作，但是在本文里还是让我们忘记它吧)。网络上是否存在另外一个系统正在密集使用一个共享的后端服务，对于实际产生的性能有很大影响。性能也许还取决于 JDBC 驱动程序版本和数据库的正确匹配。也许开发人员三年前写的一些代码恰巧在这个时候才出现特定类型的异常，而您急切需要的解决问题回馈，却恰恰包含在这个异常里。 <br />
　　从本质上说，典型业务系统的性能是由成千上万交互的变量和决策共同作用的结果。就像人体一样，有太多连锁着的部分和过程，所以很难理解系统的整体。因此我们进行了简化，并求助于拱形模式。 <br />
<br />
<strong>疾病</strong><br />
　　您看到的症状的根本原因是什么？它是初级流行性感冒或者是肺炎的开始吗？是应用程序内部的底层问题还是它所在的 JVM 外部的问题？请参阅表 1 中应用程序性能低下的一些最常见原因。
<div class="Smn995">http://www.mscto.com</div>
<p>&nbsp;</p>
<p align="center">表1
<div class="Smn995"></div>
<p>&nbsp;</p>
毛病 描述 症状 原因或治法 线性内存泄漏 每单位(每事务、每用户等)泄漏造成内存随着时间或负载线性增长。这会随着时间或负载增长降低系统性能。只有重启才有可能恢复。 随着时间越来越慢<br />
随着负载越来越慢 虽然可能有多种外部原因，但最典型的是与资源泄漏有关(例如，每单位数据的链表存储，或者没有回收的回收/增长缓冲区)。 指数方式内存泄漏 双倍增长策略的泄漏造成系统内存消耗表现为时间的指数曲线 随着时间越来越慢<br />
随着负载越来越慢 通常是由于向集合(Vector，HashMap) 中加入永远不删除的元素造成的。 糟糕的编码：无限循环 线程在 while(true) 语句以及类似的语句里阻塞。 可以预见的锁定 您需要对循环进行大刀阔斧的删剪。 资源泄漏 JDBC 语句，CICS 事务网关连接，以及类似的东西被泄漏了，造成对 Java 桥接层和后端系统的影响。 随着时间越来越慢<br />
可以预见的锁定<br />
突然混乱 通常情况下，这是由于遗漏了 finally 块，或者更简单点，就是忘记用 close() 关闭代表外部资源的对象所造成的。 外部瓶颈问题 后端或者其他外部系统（如鉴权）越来越慢，同样减缓了 J2EE 应用服务器和应用程序 持续缓慢<br />
随着负载越来越慢 咨询专家（负责的第三方或者系统管理员），获取解决外部瓶颈问题的方法。 外部系统 J2EE 应用程序通过太大或太多的请求滥用后端系统。 持续缓慢<br />
随着负载越来越慢 清除冗余的工作请求 ，成批处理相似的工作请求，把大的请求分解成若干个更小的请求，调整工作请求或后端系统(例如，公共查询关键字的索引)等。 糟糕的编码：CPU密集的组件 这是 J2EE 世界中常见的感冒。一些糟糕的代码或大量代码之间一次糟糕的交互，就挂起了 CPU，把吞吐速度减慢到爬行的速度。 持续缓慢<br />
随着负载越来越慢 典型的解决方案就是数据高速缓存或者性能计数。 中间层问题 实现得很糟糕的桥接层(JDBC 驱动程序，到传统系统的 CORBA 连接)，由于对数据和请求不断的排列、解除排列，从而把所有通过它的流量减慢到爬行速度。这个毛病在早期阶段很容易与外部瓶颈混淆。 持续缓慢
<p class="Xvx792"></p>
<br />
随着负载越来越慢 检查桥接层和外部系统的版本兼容性。如果有可能，评估不同的桥接供应商。如果重新规划架构，有可能完全不需要桥接。 内部资源瓶颈：过度使用或分配不足 内部资源(线程、放入池的对象)变得稀缺。是在正确使用的情况下加大负载时出现过度使用还是因为泄漏？ 随着负载越来越慢<br />
零星的挂起或异常错误 分配不足：根据预期的最大负载提高池的最大尺寸。过度使用：请参阅外部系统的过度使用。 不停止的重试 这包括对失败请求连续的(或者在极端情况下无休止的)重试。 可以预见的锁定<br />
突然混乱 可能就是后端系统完全宕机。在这里，可用性监控会有帮助，或者就是把尝试与成功分开。 线程：阻塞点 线程在过于积极的同步点上备份，造成交通阻塞。 随着负载越来越慢<br />
零星的挂起或异常错误<br />
可以预见的锁定<br />
突然混乱 可能同步是不必要的(只要重新设计)，或者比较外在的锁定策略(例如，读/写锁)也许会有帮助。 线程：死锁/活动锁 最普遍，这是您基本的&#8220;获得顺序&#8221;的问题。 突然混乱 处理选项包括：主锁，确定的获得顺序，以及银行家算法。
<p><strong>测量关键的统计指标</strong>
<p class="Xvx792"></p>
<br />
　　当您负责诊断问题的时候，您应当能够跟踪关于您的 WebLogic 应用程序健康情况的关键统计指标。您能测量什么？有什么工具可以提供帮助呢？ 
<p>&nbsp;</p>
<strong>使用的全部内存：</strong>在不同级别上 (JVM 堆栈，操作系统)，Java 堆栈 profiler 对堆栈的正确使用提供了可见性；像 top ,vmstat 以及 Windows Perfmon 这样的工具在操作系统级别上为内存使用提供可见性。察看 Java 堆栈的一个简单的聚合视图，请打开—verbose：gc 开关(如果在您的 JVM 上可以使用的话)。 <strong>CPU 时间：</strong>合并(可以通过使用 top 等方式得到)每个组件或每种方法。其中某些指标可以通过 WebLogic 管理控制台得到。也可以通过 Java profile 使用它们。 <strong>计时 (a.k.a.&#8220;实&#8221; 时)：</strong>每事务，每组件，每方法；可以按统计平均值或单独的数据点查看。Java profiler 可以产生一些这样的数据，但是使用程序监控解决方案可能是您的最佳选择。 <strong>内部资源：<br />
</strong>分配的数量，使用的数量，等待的客户数量，获得资源的平均等待时间，使用资源平均消耗的时间，使用资源完成请求工作时使用的平均时间。应用程序服务器通常会给出这些数字的最小可视性。 <strong>外部资源：</strong>分配的数量，使用的数量，等待的客户数量，平均等待时间，加上对这些外部系统的直接测量(例如查看它能多快完成请求的工作)。不要忘记运行应用程序服务器的操作系统和硬件也是&#8220;外部资源&#8221;-例如，是否您使用了太多的进程或端口？可以用两种形式测试这些资源—从 JVM 内部测试提供资源的桥接层，用外部资源本身的工具测量外部资源。 <strong>网络应用：</strong>带宽使用，延迟。虽然操作系统自带的工具(例如 netstat)也有助于做这些工作，但是网络嗅探器设备可以深入了解这些信息。 <strong>系统状态：</strong>用线程清除，日志和跟踪文件，堆栈跟踪等等。或者在更深层次上，就像调试器中查看的那样使用变量的值。
<p><strong>实验工作</strong><br />
　　有的时候，在一次标杆运行中获得的数据，不足以揭示答案。那么找到答案的机会就在于您还有些有限的预算，可以运行试验或者做实验工作，来完成诊断。您可以运行什么类型的试验呢？您可以修改、观察什么变量呢？
<p class="Vag999">http://www.mscto.com</p>
<p>&nbsp;</p>
尝试观察系统行为在一段时间上的变化。应用一个衡定的负载，并观察您的指标随时间发生的变化。您可能会看到某些趋势，短则一小时就可看到，长则二三天。例如，您可以看到内存使用随着时间而增长。随着使用的内存数量达到上限， JVM 花在搜索垃圾上的时间和操作系统花在分配内存页面上的时间开始减少用户事务的整体响应时间。当抛开 GC 的时候，垃圾搜集的整个过程可能过长，从而造成执行中的事务超时和异常。现在可以开始查找资源泄漏或内存泄漏了。 尝试在系统上改变负载。 采用三到四种工作负载(例如，10个，50个和100个用户)，并搜集每个负载的数据。分析一下您对这些负载的测量情况。例如，您可能发现，当您的账户登录 servlet 的响应时间无论如何都会低于 50 毫秒的时候，计算销售税的 EJB 却随着用户数据的增长，速度呈线性下降。如果这个 EJB 性能在负载下的差异能解释整体响应时间性能在负载下的增长，那么现在就是深入分析这个组件的时候了。谨记一定还要把负载恢复原状，并查看系统是否复原。 尝试把系统分成小单元，针对每个单元轮流进行压力测试。 选择一个或多个坐标系对系统进行划分。主要的一个是系统面上的层：负载均衡器、Web 服务器、WebLogic Server，以及后端。其它示例包括用户账户，内部组件，事务类型，以及单独的页面。假设您选择了用户账户。在用户 A 的账户下运行一些负载，然后再在用户 B 的账户(应当非常不同)下运行某些负载；比较两次运行间不同的测量结果。或者，轮流选择您使用的后端系统，分别对使用每个后端系统比较重的应用程序组件进行压力测试。具体要选择哪个坐标进行划分，完全取决于您要证明或者否定哪个假设。下面是一些具体想法： <font color="#ffffff"></font><br />
　　- 如果某个用户的登录看起来造成了问题，那么有可能是这个用户账户档案(例如，装入 2,000 个订单的完整采购历史)，或者可能是他使用系统的方式(例如，页面访问的顺序，或者他用来查找某个文档的查询字符串的正确性)。<br />
　　- 如果您使用的是一个集群系统，请尝试以单台机器为单位划分。尽管尽了最大努力，有的时候还会有一些机器没有安装最新的应用服务器或者操作系统补丁，这就会造成不同的性能特征。而且，还请注意负载均衡器，或者保姆进程，查看它们是否公平地分配了工作并跟踪了进入请求。
<p><strong>诊断：测试您的推测</strong><br />
　　在这个时候，您应当已经有了足够的信息，可以形成关于性能瓶颈原因的推测了(请参阅表 1)。为了验证您的推测是否正确或者在多个备选的推测之间进行筛选，您需要分析更多的信息或者在系统上运行更多的标杆测试。这里是一些可以帮助您的指导意见： <br />
区分糟糕的编码(或者是应用程序组件或者是桥接层)和瓶颈 (内部的或外部的)，请查看整体的 CPU 使用情况。如果它在负载下没变化，但是整体响应时间变化了，那么就是应用程序花费了它的大多数时间来等待。 仅仅是因为好像是外部资源的问题，不代表您就可以立刻把责任推到资源上。 例如，分层或联网的问题，也能造成数据库看起来很慢，虽然实际上它并不慢。或者，更简单一点，您对数据库的请求可能是不合理的(每次用户登录的时候，都要进行三个表之间的 200 万行记录合并)。应当一直把桥接层的响应时间(例如，JDBC 驱动器)和资源提供的时间或者工具提供的时间进行比较(例如，DBA Studio)。 结构化的图表有助于您理解系统内部的整体交互，但是不要忘记地图并不是领地。.编码错误或者对架构意图的误解，有可能使系统的实际行为与期望的行为不同。请相信性能工作提供的实际数据，而不要相信一个声称&#8220;每个用户事务将只会发布一个 SQL 语句&#8221;这样的文档。 使用 Occam 军刀。 假设您有两个备选推测，一个是：在 200 万行代码里，有一个编码糟糕的组件，直到上周这个组件才集成进来；另一个是 JVM 的即时编译器生成了糟糕的机器码，破坏了这个变量的内存完整性。除非您有具体的数据来证实，否则(我已经看到了第二种情况发生)，请更详细地检查第一个假设。J2EE 系统确实容易出错，但是不要让这一点就妨碍您先测试一个更简单的假设。 日志文件中没有错误不代表不存在错误。 有许多原因可以造成不在日志里写下异常；可能是因为程序员认为某件事&#8220;永远不会发生&#8221;，于是就排除了这个异常；也可能是因为某些组件可以使用故障恢复机制，所以就没有记录第一次故障。 </p>
<p><strong>示例诊断</strong> <font color="#ffffff"></font><br />
　　让我们来实际研究一个示例。您的 WebLogic 应用程序表现出在负载下越来越慢的症状。您加入的用户越多，系统越慢。一旦消除负载，系统就冷静下来，没有任何后遗症。您对这一主要症状进行测试，发现并得到图 2 所示的以下结果(时间测量针对的是单一典型事务的端到端完成时间)。 </p>
<p align="center">表2 </p>
<p>负载(用户数) 来回用时(毫秒) 10 300 50 471 100 892 150 1067 </p>
<p align="center"><strong>应用程序性能在负载下越来越慢</strong>
<p class="Cwv572">http://www.mscto.com</p>
<p>&nbsp;</p>
<p>　　您形成了几个假设。也许这里的毛病是一个糟糕编码的组件，也许是后端系统的瓶颈。它可能是一个同步阻塞点。您怎样才能分清它们的不同呢？假设您还测试了应用程序服务器在负载运行期间的CPU整体使用情况，并得到了表 3 所示的结果。 <font color="#ffffff"></font></p>
<p align="center">表3
<div class="Cwv572"></div>
<p>&nbsp;</p>
<p>负载(用户数) 来回用时(毫秒) 整体 CPU 时间(%) 10 300 30 50 471 33 100 892 37 150 1067 41 </p>
<p align="center"><strong>问题看起来好像是&#8220;等待&#8221;瓶颈</strong>
<p class="Cwv572"></p>
<p>&nbsp;</p>
<p>　　现在看起来，系统不是 CPU 密集型的，这就是说它的多数时间都花在等待上了。那么是它的内部(例如，同步交通阻塞)或外部(缓慢的数据库)的问题？好，让我们假设我们还稍微多搜集了一些数据，如表 4 所示。
<div class="Cwv572"></div>
<p>&nbsp;</p>
<p align="center">表4 <font color="#ffffff"></font></p>
<p>负载(用户数) 等待数据库连接的线程数量 JDBC 查询用时(毫秒) 10 2 58 50 3 115 100 3 489 150 4 612 </p>
<p><br />
<strong>问题是否出在一个缓慢的 SQL 语句上呢？<br />
</strong></p>
现在看起来并不是内部等待数据库连接的瓶颈，相反，好像是 JDBC 查询本身的问题。JDBC 查询不仅随整体事务时间的不同而不同，而且它糟糕的性能还解释了整体性能糟糕的原因。但是，我们还不能完全确定。您仍然还有三个主要的假设要排序：是否数据库本身慢？应用程序是否对数据库进行了不合理的请求？或者问题是不是出在应用程序和数据库之间的某个层上？您拿出数据库供应商专用的工具，从它的角度查看响应时间。假设您看到如表 5 所示的数字。 <font color="#ffffff"></font>
<p align="center">表5
<div class="Gor489"></div>
<p>&nbsp;</p>
负载(用户数) JDBC 查询计时(毫秒) DB SQL 执行的时间(毫秒) 10 58 43 50 115 97 100 489 418 150 612 589 <br />
<strong>实际是数据库中的 SQL 语句慢 </strong>
<p align="left">　　如果您没有看到这条信息，那么您可能要返回 JDBC 驱动程序，期待能够发现其中的某些同步问题(请记住，CPU 没有被抑制)。幸运的是，在这个案例里，您已经把具体问题的范围缩小到数据库查询上。找出查询请求是否足够合理，需要一些相关领域的知识，需要熟悉系统，但是在这个案例里，它也许就是发现查询把非索引字段和外键进行了比较。您和 DBA 协作，它修改索引方案，让查询变得更快，而您则找到了您的药方。 <br />
<br />
<strong>结束语</strong><br />
　　诊断 WebLogic J2EE 应用程序的性能瓶颈是一个艰苦的旅程。请随时保持清醒，把事实与推测分开，总是用实际的证据来确认您的推测。我希望给您带来了思考和实践问题的一些有用的想法的分类。就像调试，这仍然是一项不明确的艺术，但是深思熟虑会带您走出困境。祝您好运!
<div class="Gor489"></div>
<p>&nbsp;</p>
<p align="left"><strong>关于作者</strong><br />
　　John Bley 是 Wily Technology 的软件工程师。他有丰富的 Java 编程和架构经验。为了撰写本文，他总结了 Wily 的企业客户的经验，Wily负责管理复杂的 J2EE 环境。(更多)<br />
原文出处 http://www.sys-con.com/story/?storyid=43024&amp;DE=1<br />
</p>
<img src ="http://www.blogjava.net/caizh2009/aggbug/312097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-02-05 13:32 <a href="http://www.blogjava.net/caizh2009/archive/2010/02/05/312097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google网站性能优化工具Page Speed试用报告</title><link>http://www.blogjava.net/caizh2009/archive/2010/02/05/312095.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Fri, 05 Feb 2010 05:22:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/02/05/312095.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/312095.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/02/05/312095.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/312095.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/312095.html</trackback:ping><description><![CDATA[<p>Google近日推出了一款网站性能优化工具：Page Speed（<a href="http://code.google.com/intl/zh-CN/speed/page-speed/docs/using.html" target="_blank">http://code.google.com/speed/page-speed/</a>）。它旨在帮助站长与网站开发者分析网站中存在的性能方面的问题，并有针对性地提出改进意见。Page Speed在功能方面极其类似于Yahoo!的网站性能优化<a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a>，不过YSlow要比Page Speed推出早得的多。它们都是基于Firebug的Fireffox插件，使用方法也类似。这里我主要介绍一下Google新推出的Page Speed的使用，对Yslow感兴趣的朋友可以参照我以前的这篇文章《<a href="http://www.dudo.org/article/WebDev/220.htm" target="_blank">你的网站为什么会慢？——用YSlow为你的网站提速</a>》，同时还有我翻译的Yahoo!的文章Yahoo!网站性能最佳体验的34条黄金守则——<a href="http://www.dudo.org/article/WebDev/214.htm" target="_blank">内容</a>、<a href="http://www.dudo.org/article/WebDev/216.htm" target="_blank">JavaScript和CSS</a>、<a href="http://www.dudo.org/article/WebDev/215.htm" target="_blank">服务器</a>、<a href="http://www.dudo.org/article/WebDev/218.htm" target="_blank">图片、Coockie与移动应用</a>，相信一定会对你提高网站性能有帮助。</p>
<h4>一、Page Speed的安装及使用</h4>
<p>Page Speed是一款Firefox插件，同时他依附于别款插件<a href="http://getfirebug.com/" target="_blank">Firebug</a>，也就是说你的Firefox浏览器中必须已经安装了Firebug才能安装Page Speed。安装环境为Firefox 3.0.4以上，Fireug 1.3.3以上。</p>
<p>Page Speed的使用也很简单，在Firefox中点击右下角的Firebug图标启动后，再点击Page Speed选项卡即可。要注意的是，你要对你网站内的某个页面进行性能分析，你必须先把该页面加载完成后才能使用Page Speed，也就是说只有在浏览器左下角出现&#8220;Done&#8221;或者"完成"之后才可以启用Page Speed进行分析。如果页面中流媒体，可能不会现在&#8220;完成&#8221;，这种情况要等到流媒体可以播放。<br />
<br />
&nbsp;<img alt="page speed启动界面" src="http://www.dudo.org/attachments/month_0906/q20096610240.png" /><br />
<br />
然后点击&#8220;Analyze Performance&#8221;（性能分析），这时Page Speed会根据web performance best practices （网页性能最佳实践）进行逐项打分。然后根据重要程序和优先级对每项进行排列。<br />
<br />
<img alt="Page Speed运行界面" src="http://www.dudo.org/attachments/month_0906/7200966103236.png" /></p>
<p>此外，你还可以点击每条建议前面的&#8220;加号&#8221;展开查看详细的描述，或者直接点击每条规则相看该规则的具体内容，还可以点击&#8220;Show Resource&#8221;（查看来源）来查看每条建议是针对页面中哪部分内容提出的。</p>
<p>对于分析结果中的符号说明一下：</p>
<ol>
    <li>红色感叹号代表高优先级提示，表示这一项严重影响了你的页面性能，你需要优先对其进行性能优化；
    <li>橙色三角代表此项提示需要引起你的注意，并进行适当改进；
    <li>绿色的对号代表该项规则在你的网站中应用得到，你在修改了前面两部分的提示之后，它们有可能变为绿色的对号；
    <li>蓝色消息符号是为你提供了额外的帮助信息，请稍加留意（需要注意的是，如果你的页面中出现了大量的此类符号，可能是因为你在页面加载完成之前就进行了网站性能分析）。 </li>
</ol>
<h4>二、活动记录</h4>
<p>活动记录是一条页面活动的时间轴，它记录了包括网络事件、JavaScript运行在内的所有浏览器活动。你可以使用它并配合性能分析中的数据进一步对网站性能做出评估。</p>
<ul>
    <li>查看页面运行过程中所耗费的时间，以毫秒计算；
    <li>查看浏览器事件，包括页面加载完成后的事件；
    <li>区分造成页面响应缓慢的原因，其中包括网络来时、DNS查找、连接建立、JavaScript运行等；
    <li>获取在特定时间或者事件下才响应的JavaScript事件列表；
    <li>可以对其它标签或者窗口中打开的页面进行分析；
    <li>多页面加载时的页面加载顺序；
    <li>对根据Page Speed优化前后的表现进行对比。 </li>
</ul>
<p><a title="在新窗口打开图片" href="http://www.dudo.org/attachments/month_0906/a200966105446.png" target="_blank"><img alt="Page Speed 页面活动记录" src="http://www.dudo.org/attachments/month_0906/a200966105446.png" width="550" /></a></p>
<h4>三、理解Page Speed中的事件</h4>
<p>页面记录选项卡下是通过时间线来记录各种资源加载到页面所有需要的时间。事件的记录时间间隔为10毫秒，如果事件需要的时间少于10毫秒那么它将用较短的色块来表示。时间线中没有任何颜色的表示，在浏览器事件的运行依赖于其它进程，如DOM和CSS渲染、Flash ActionScript、渲染、操作系统事件等。</p>
<table style="clear: right; border-right: rgb(51,102,204) 1px solid; border-top: rgb(51,102,204) 1px solid; margin: 1em 0px 0px 1px; border-left: rgb(51,102,204) 1px solid; line-height: 125%; border-bottom: rgb(51,102,204) 1px solid; border-collapse: collapse; border-spacing: 0pt">
    <tbody>
        <tr>
            <th width="88" colspan="2">网络事件</th>
            <th width="488">描述</th>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(85,85,85)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">DNS</td>
            <td width="488">浏览器查找DNS所需要的时间</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(153,153,153)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">t连接等待</td>
            <td width="488">浏览器与网站服务器建立连接（TCP）需要一定的时间。由于浏览器可以打开的连接数目是有限的，如果达到这个限制他必须等其它连接关闭之后才能再重新建立一个新的连接。（更多关于浏览器连接的信息可以参照<a href="http://www.dudo.org/speed/page-speed/docs/rtt.html#ParallelizeDownloads">Parallel downloads across hostnames</a>）。 这个事件显示了浏览器等其它连接完成的时间。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(228,213,14)" width="5">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">连接</td>
            <td width="488">浏览器和web服务器建立连接。这个事件只有打开新连接时出现，已有连接重新打开使用不包含在内。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(40,176,180)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">请求发送</td>
            <td width="488">浏览器发送的HTTP请求。只显示GET方式的请求。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(221,221,221)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">已连接</td>
            <td width="488">浏览器通过网络等待接收数据。事件随着浏览器TCP连接的结束而结束。</td>
        </tr>
        <tr>
            <th width="88" colspan="2">本地事件</th>
            <th width="488">描述</th>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(224,104,0)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">缓存</td>
            <td width="488">浏览器成功将内容加入到缓存中。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(51,153,51)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">可用数据</td>
            <td width="488">可用于浏览器呈现的数据。由于web服务器发送大量的数据，如果文件很大那么有可能一个资源会出现多个该事件。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(195,67,73)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">&nbsp;获取JS</td>
            <td width="488">浏览器获取JavaScript。该事件可能会延缓其它事件，如果此种情况出现，将会在其下一行列出。</td>
        </tr>
        <tr>
            <td width="37">
            <table>
                <tbody>
                    <tr>
                        <td style="background-color: rgb(33,90,167)">&nbsp;</td>
                    </tr>
                </tbody>
            </table>
            </td>
            <td width="51">运行JS</td>
            <td width="488">浏览器执行JavaScript。该事件可能会延缓其它事件，如果此种情况出现，将会在其下一行列出。如果获取JS和运行JS中间有时间间隔，这说明源文件中包括有延时功能的函数。</td>
        </tr>
    </tbody>
</table>
<p>此外，Page Speed还包括了对已完成的JavaScript函数的信息搜集功能，当页面中的JS函数一旦运行，PageSpeed就会捕捉到相关信息。不通过对Page Speed进行设置还可以对未触发函数、延时加载函数等进行收集。</p>
<p>下面的图片显示了7800毫秒时已经加载但还未触发的函数列表：<br />
<br />
<img alt="Page Speed活动记录——JS收集" src="http://www.dudo.org/attachments/month_0906/9200966113242.png" /></p>
<p>而下面则显示是已经触发运行了的JS函数：<br />
<br />
<img alt="Page Speed" src="http://www.dudo.org/attachments/month_0906/4200966113440.png" /></p>
<p>此外Pge Speed还有诸如JavaScript函数控制、浏览器User Agent设置等更高级功能。具体使用大家可以与YSlow对比一下。</p>
<p>相信，用好这两款工具，对于站长和网站开发者来说会有极大的帮助。</p>
<p>本文网址：&nbsp;<a href="http://www.dudo.org/article/NewSoftware/using_google_page_speed.htm">http://www.dudo.org/article/NewSoftware/using_google_page_speed.htm</a><br />
转载请注意出处</p>
<img src ="http://www.blogjava.net/caizh2009/aggbug/312095.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-02-05 13:22 <a href="http://www.blogjava.net/caizh2009/archive/2010/02/05/312095.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>