【问题标题】:Java Webapp Performance IssuesJava Webapp 性能问题
【发布时间】:2012-01-19 13:51:14
【问题描述】:

我有一个完全用 Java 制作的 Web 应用程序。 Webapp 不使用任何图形/模型框架,相反,webapp 使用模型视图控制器。它仅使用 Servlet 规范(Servlet 2.4 版)制作。 自 2001 年以来开发的 webapp,它非常复杂。最初,它是为与 Tomcat 4.x/5.x 一起工作而构建的。实际上,在 Tomcat 6.x 上运行。但是,我们仍然有内存泄漏。

在深度上,Webapp 的规格可以恢复为:

  • 使用 Servlet v. 2.4 规范。
  • 它不使用任何框架
  • 它不使用 JavaEE(不是 EJB)
  • 它基于 JavaSE(带有 Servlet)
  • 仅适用于 IE 6+(因为它的年龄)

基础设施规范

实际上,webapp 可以在三种环境中工作:

第一

  • IBM 服务器(具体型号我记不清了)
  • 英特尔至强 2.4 Ghz
  • 32GB 内存
  • 1TB 硬盘
  • Tomcat(版本 6)配置为使用 8GB 内存

第二

  • 戴尔服务器
  • 英特尔至强 2.0Ghz
  • 4GB 内存
  • 500GB 硬盘
  • Tomcat(5.5 版)配置为使用 1.5GB 内存

第三

  • 戴尔服务器
  • AMD 皓龙 1214 2.20Ghz
  • 4GB 内存
  • 320GB 硬盘
  • Tomcat(版本 6)配置为使用 1.5GB 内存

数据库规范

webapp 使用 SQL Server 2008 R2 Express Edition 作为 DBMS,但第一个服务器规范的用户除外,它使用 SQL Server 2008 R2 Standard Edition。对于连接池,该应用使用 Apache DBCP。

问题

嗯,它有非常严重的性能问题。 webapp 不断变慢,并且多次拒绝服务。恢复应用程序的唯一方法是重新启动 Apache Tomcat 服务。 在性能审核期间,我发现了几个编程问题(例如永远不会关闭的数据库连接、过度使用 Vector 集合 [而不是 ArrayList])。

我想知道如何提高应用程序的性能,哪些应用程序可以帮助我监控 Tomcat 性能和 Webapp 内存使用情况。

我们很乐意接受所有建议。

【问题讨论】:

  • 您是否真的尝试过任何方法来找出瓶颈所在?堆转储以查找内存泄漏?分析以查看是否有任何东西占用了处理器周期?像New Relic 这样的放缓只是随着时间的推移才变得明显?除了听起来不确定的“审计”之外还有什么?
  • 你的 Java 内存参数是什么?
  • 因为如果不是这样,这个问题对于 SO 来说听起来太开放了,正如the FAQ 所说:“如果你能想象一本书可以回答你的问题,那你就问得太多了。”

标签: java performance sql-server-2008 web-applications tomcat6


【解决方案1】:

你也可以试试stagemonitor。它是一个开源的性能监控库。它记录请求响应时间、JVM 指标、请求详细信息,包括请求期间被调用方法的调用堆栈(配置文件)等等。由于开销低,您也可以在生产中使用它。

调整过程如下。

  • 使用请求仪表板识别慢速请求
  • 使用Request Detail Dashboard 分析请求的堆栈跟踪以了解慢速方法
  • 深入您的代码并尝试优化那些缓慢的方法
  • 您还可以将吞吐量或会话数等一些指标与响应时间或 CPU 使用率相关联
  • 使用JVM Memory Dashboard 分析堆

注意:我是stagemonitor的开发者。

【讨论】:

    【解决方案2】:

    我将从一些可以帮助您分析应用程序的工具开始。由于您正在开发 webapp,所以从 Lambda ProbeJava melody 开始。

    第一步是确定应用开始出现异常行为的条件。问自己几个问题:

    1. 性能问题是在应用程序启动后立即出现还是超时出现?
    2. 性能问题是否与客户端请求的数量相关?
    3. 真正的性能问题是什么 - 服务器负载高或内存不足(注意它们是相关的,因此请检查哪个先启动)
    4. 是否有任何后台进程正在执行一些大规模的操作?它们是否计划在某个特定时间段运行?

    在深入代码之前尝试找到一些线索。它将帮助您缩小可能的原因。

    正如 Joshua Bloch 在其题为“Effective Java”的书中所说的那样 - 性能问题很少是源代码中一些小错误的影响(当然,滥用 Java 结构会导致灾难)。通常原因是糟糕的系统 (API) 架构。

    基于我的经验的最后一个建议 - 尽量不要认为高内存消耗是一件坏事。 Tomcat 将使用与操作系统一样多的内存,而 JVM 将允许他(不超过最大设置)并且当它需要更多时 - Tomcat 将执行垃圾收集。所以一个典型的(正确的!)内存消耗图看起来像一把锯子。如果您正在处理内存泄漏,那么图表将不断增加,但无限期地增加。这是最常被误解的内存泄漏,因此请牢记。

    说实话 - 我们无法为您提供更多帮助。这些只是提示,现在您必须进行广泛的研究才能找出原因:)

    【讨论】:

    • 我曾经使用 Javamelody 做了很多改进。您将其作为 servlet 过滤器和 JDBC 代理。如果您使用过一些框架(例如 EJB、Spring、Guice),它会容易得多。我也同意它看起来像内存泄漏。
    • @ŁukaszBachman 好的,看起来不错!我来看看工具。我有一个问题:确切地说,为什么“编程问题”不能成为内存消耗/性能问题的主要原因?
    • @Astantler - 好吧,他们可能是,但通常不是 :) 我会给你发私信,cmets 太短了 ;)
    • 有时只是一开始就做错了事,这就是我所说的糟糕的 API 使用的意思。例如 - 我们有一个“Hibernate 问题”导致我们的应用程序产生巨大的数据库负载。我们假设程序员在应用程序的某些部分出错,原因是 Hib 错误。会话管理,因此 - 不必要的对象初始化。或者一旦我们有大量空闲的 MySQL 连接没有被连接池关闭。我们花了数小时调整连接池设置,问题在于提供的数据源实现不正确。
    【解决方案3】:

    一般的解决方案是使用分析器,例如YourKit,具有重现问题的真实工作负载。

    我首先要做的是仅 CPU 配置文件、仅内存配置文件,最后是 CPU 和内存配置文件(然后我查看 CPU 配置文件结果)

    YourKit 还可以监控您的高级操作,例如 Java EE 资源和 JDBC 连接。我没有尝试过这些,因为我不使用它们。 ;)

    即使不是问题的原因,提高效率也是一个好主意,因为它会减少这些配置文件中的“噪音”量并使您的问题更加明显。

    您可以尝试增加可用内存量,但怀疑它只会延迟问题。

    【讨论】:

      【解决方案4】:

      好的。所以我看到大型 Java 应用程序运行较少的配置。您应该尝试执行以下操作 -

      1. 首先将 Profiler 连接到您的应用程序,然后查看应用程序的哪个部分花费的时间最多。您可以使用JProfilerEclipse MAT(我个人更喜欢JProfiler)。还要尝试查看占用最多内存的对象。这将帮助您缩小到需要重写以提高性能的部分。

      2. 一旦您查看了内存泄漏,请更新您的应用程序以使用 64 位 JDK(假设它已经不这样做)

      3. 查看您的 JVM 参数并对其进行优化。

      【讨论】:

      • 好的,但我有一些关于你所说的问题:
      • 1. 64bit JDK:它提高了一般性能吗?有什么区别?对不起,但我完全无法理解。 2. 优化 Tomcat 参数:这些是我在 Tomcat 6 中的参数:pastebin.com/ZM1bTHTf 最近,我添加了“-XX:GCTimeRatio=9”来增加垃圾收集。我不知道这个参数是否会提高内存使用率。 “优化它们”是什么意思?
      【解决方案5】:

      您可以尝试使用开源工具Webapp Watcher 来确定代码中哪里存在性能问题。

      您必须首先在 webapp (as explained here) 中添加一个过滤器以记录指标,然后在WAW Analyzer 工具中导入日志并按照步骤described in the doc 了解潜在的性能问题在哪里在代码中。

      【讨论】:

        猜你喜欢
        • 2016-02-13
        • 1970-01-01
        • 1970-01-01
        • 2011-12-06
        • 2014-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-14
        相关资源
        最近更新 更多