5

我使用的重要技术有:Glassfish v3、JSF 2.0、JPA 2.0、EclipseLink 2.0.2、log4j 1.2.16、commons-logging 1.1.1。

我的问题是应用程序的某些部分非常慢。我使用netbeans 6.8 Profiling功能对此进行了分析。

I. 日志- 我使用 log4j 和 apache commons 日志在日志文件和控制台中生成日志。日志也出现在 glassfish 的服务器日志中。我使用记录器如下:

    private static Log logger = LogFactory.getLog(X.class);
    ...
    if (logger.isDebugEnabled()) {
        ...
        logger.debug("Log...");
    }

问题是有时这样短的语句需要很长时间(大约 800 毫秒)。当我切换到 java.util.logging 时,它还不错,但也很慢(200 ms 波段)。有什么问题?我需要一些日志记录...更新- 从 Netbeans 6.8 切换到 Netbeans 6.9.1 后,日志记录缓慢的问题得到了解决。- 当日志打印到它的控制台时,Netbeans 6.8 可能非常慢?!所以它与 Log4J 或公共日志记录无关。

二、DB 操作:我第一次调用以下 EJB 的 find 方法需要 2,4 秒!其他呼叫仅持续几毫秒。那么为什么第一次手术要花这么长时间呢?这是(仅因为)连接建立还是与 XFacade 的依赖注入有关,以及这些注入何时执行?:

@Stateless
@PermitAll
public class XFacade {
    @PersistenceContext(unitName = "de.x.persistenceUnit")
    private EntityManager em;
    // Other DI's
    ...

    public List<News> find(int maxResults) {
      return em.createQuery(
      "SELECT n FROM News n ORDER BY n.published DESC").setMaxResults(maxResults).getResultList() 
    }
}

三、依赖注入,JNDI 查找:DI 之类的(@EJB ...)和 InitialContext 查找与性能有关吗?注入本地、远程和无接口 EJB 之间是否存在差异(性能视图)?

四。Managed Beans - 我使用了许多 Session Scoped Beans,因为 ViewScope 似乎有很多错误,并且 Request Scoped 并不总是实用的。有替代方案吗?- 因为这些 Bean 并不慢,但在整个会话期间服务器端内存压力很大。当用户注销时,它需要一些时间!

V. EJB——我不只使用 MDB 会话 Bean 和单例 Bean。他们经常使用@EJB注解注入其他 Bean。一个 Singleton Bean 使用@Schedule Annotations 来启动重复操作。我发现一个有趣的事情是,从 EJB 3.1 开始,您可以使用@Asynchronous Annotation 使 Session Bean Method 异步。在实施有关性能的 EJB 时,我通常应该考虑什么?

也许有人可以给我一些一般和/或具体的技巧来提高 javaee 应用程序的性能,特别是关于上述问题。谢谢!

4

2 回答 2

4

首先,您应该使用负载测试工具在真实环境中测试您的应用程序,您无法从您在 IDE 中观察到的行为中真正得出有效的结论。最重要的是不要忘记分析实际上会改变性能。

I. Logging (...) 从 Netbeans 6.8 切换到 Netbeans 6.9.1 后,记录缓慢的问题得到解决

这是您不能使用信任 IDE 内部行为的第一个证据。

二、DB操作:我第一次调用以下EJB的find方法需要2,4秒!其他呼叫仅持续几毫秒。那么为什么第一次手术要花这么长时间呢?

可能是因为某些 GlassFish 服务是(延迟)加载的,可能是因为无状态会话 bean (SLSB) 必须被实例化,可能是因为EntityManagerFactory必须创建。简介说了什么?为什么在激活应用服务器日志记录时会看到?由于后续调用正常,有什么问题?

三、依赖注入,JNDI 查找:像 (@EJB ...) 这样的 DI 和关于性能的 InitialContext 查找有区别吗?

JNDI 查找成本高昂,在良好的旧服务定位器中使用一些缓存是一种事实上的做法。因此,我不认为使用 DI 时性能会最差(我实际上希望容器擅长它)。老实说,这对我来说从来都不是问题。

当您进行性能优化时,典型的工作流程是 1) 检测缓慢的操作 2) 找到瓶颈 2) 处理它 3) 如果操作仍然不够快,请返回 2)。根据我的经验,瓶颈在 DAL 中占 90% 的时间。如果您的瓶颈是 DI,则 IMO 没有性能问题。换句话说,我认为您担心太多,并且非常接近“过早优化”。

四。Managed Beans - 我使用了许多 Session Scoped Beans,因为 ViewScope 似乎有很多错误,并且 Request Scoped 并不总是实用的。有替代方案吗?- 因为这些 Bean 并不慢,但在整个会话期间服务器端内存压力很大。当用户注销时,它需要一些时间!

我没有看到任何问题:) 所以我无话可说。更新(回答评论):使用对话范围可能确实更便宜。但与往常一样,测量。

V. EJB——我不只使用 MDB 会话 Bean 和单例 Bean。他们经常使用@EJB 注解注入其他 Bean。一个 Singleton Bean 使用 @Schedule Annotations 来启动重复操作。我发现一个有趣的事情是,从 EJB 3.1 开始,您可以使用 @Asynchronous Annotation 使 Session Bean Method 异步。在实施有关性能的 EJB 时,我通常应该考虑什么?

SLSB(和 MDB)总体上表现非常好。但是在使用 SLSB 时要记住以下几点:

  • 如果您的客户端和 EJB 并置以避免远程调用的开销,则Local首选接口。Remote
  • 仅在必要时使用有状态会话 Bean (SFSB)(它们更难使用,管理状态有性能成本,并且它们本质上不能很好地扩展)。
  • 避免过多地链接 EJB(特别是如果它们是远程的),更喜欢粗粒度的方法而不是多个细粒度的方法调用。
  • 调整 SLSB 池(以便您有足够的 bean 来为并发客户端提供服务,但不要太多以避免浪费资源)。
  • 适当地使用事务(例如,将 NOT_SUPPORTED 用于只读方法)。

我还建议不要使用某些东西,除非你真的需要这个功能并且有一个真正的问题需要解决(例如@Asynchronous)。

也许有人可以给我一些一般和/或具体的技巧来提高 javaee 应用程序的性能,特别是关于上述问题。谢谢!

专注于您的数据访问代码,我很确定这代表了大多数业务流程执行时间的 80%。

正如我已经暗示的那样,你确定你真的有性能问题吗?我不相信。但如果你真的是,请在你的 IDE 之外测量性能。

于 2010-08-22T01:14:38.603 回答
1

我同意 Pascal Thivent 的观点,因为“过早的优化”是不好的。设计好你的代码,然后担心性能。

此外,您可以针对性能或内存节约进行优化。选择哪一个让你早上头疼,并针对它进行优化。

我真的很喜欢 NetBeans 的分析器;这是最好的免费之一,恕我直言。

我会推荐:

  1. 性能分析,但将范围限制在您自己的包(例如,de.x)或排除 Java 核心类。这样您的应用程序就不会因分析而陷入困境并给您误导性的性能数据。基本上,尽量使“开销”尽可能低,如底部的条所示。

替代文字

  1. 浏览您的 Web 应用程序一段时间,看看是什么占用了您的大部分 CPU 时间。另请注意,某些对象是延迟加载的,因此第一次访问代码片段时可能会很慢。此外,您正在使用 JIT 编译器,因此代码在您第一次(或第二次......)运行时可能会很慢,但随着您更频繁地使用该代码,它会变得更快。简而言之,使用网络应用程序一段时间。您可以使用Selenium “录制”网络会话并“播放”它。这将使您获得更好的性能指标,并查看您的应用程序真正慢的地方,而不是测量“预热时间”。

  2. 如果有一段特定的代码或类给您带来麻烦,请使用分析点来准确了解导致该代码变慢的原因。

如果您有一段特定的代码导致您出现问题,请随时发布。

于 2010-08-23T12:45:47.313 回答