EJB 3.2性能下降

时间:2016-09-28 09:56:08

标签: performance ejb

我目前正在将EJB项目从2.0版升级到3.2版(所有有状态)。业务逻辑保持不变,唯一改变的是EJB部分(用注释替换描述符文件,使用注入点而不是传统查找等)。 从请求处理的角度来看,一切似乎都运行良好,问题在于性能。 使用一个连接的客户端,每个请求大约需要300毫秒。如果我添加第二个客户端,平均时间会跳到700毫秒。对于第三个客户端,平均值超过1秒,依此类推。使用EJB 2.0版本,处理时间略有增加(50~100ms),即使有更多客户端,也无需担心。

退化非常明显,我无法弄清楚原因。

我已经玩过EJB超时,事务类型等,但没有运气。我也尝试过分析服务器(通过JMC),但找不到任何可疑的东西。

好像所有请求都是按顺序处理,而不是同时处理。

有人可以提供一些可能原因的提示吗?我有什么配置吗?

注意: WebSphere 9和GlassFish 4.1.1都出现了问题,因此它显然是应用程序的问题。

编辑#1

检查应用程序的日志后,我可以确认请求是按顺序处理的,不是并发处理。

按照迈克尔的建议,我查看了一个线程转储,并且在给定的时刻,我有:

  • 27 RUNNABLE
  • 18 TIMED_WAITING(在对象监视器上)
  • 6 TIMED_WAITING(停车)
  • 16 TIMED_WAITING(睡觉)
  • 23 WAITING(在对象监视器上)
  • 40等待(停车)

没有线程受阻的迹象。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

你是如何测试的?

这听起来像多个客户端正在获得相同的有状态会话bean实例。

容器将序列化对同一SFSB实例的调用。它应该这样做,如果它之前没有发生,那么你可能有一些平台相关的部署描述符禁用了这种行为。

但是,如果您正在使用测试框架并且所有客户端都在进行相同的会话,那么这也会使您看起来遇到问题。

§4.3.13EJB规范的“序列化会话Bean方法”说:

  

容器序列化对每个有状态和无状态会话的调用   bean实例。大多数容器都支持a的许多实例   会话bean并发执行;但是,每个实例只能看到   方法调用的序列化序列。因此,有状态或   无状态会话bean不必编码为可重入。

如果您在所有客户端之间共享单个SFSB实例,则可能适合将其从@Stateful更改为@Singleton。 Singleton EJB通过@ConcurrencyManagement@Lock注释提供明确的重入控制。如果您对EJB的线程安全性完全满意,那么您可以通过以下方式标记您的bean:

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class MyStatefulSessionBeanMasqueradingAsASingleton {
    ...
}