2016-09-28 103 views
0

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

退化很明显,我只是无法弄清原因。

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

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

有人可以提供一些可能的原因提示?有没有我错过的配置?

注意:这个问题同时出现在WebSphere 9和GlassFish 4.1.1上,所以这显然是一个应用程序的问题。

编辑#1

检查应用程序的日志后,我可以证实,请求被处理顺序,没有并发。

继迈克尔的建议,我看着一个线程转储,并在给定时刻,有:

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

没有阻塞线程的迹象。

有什么想法?

+0

尝试负载测试期间获得线程转储5+用户。我想有共享资源需要独占锁。 –

+0

@迈克尔,我没有太多分析线程转储的经验。我究竟应该寻找什么? –

+0

简单的方法采取线程转储:jstack >> myapp.log。当你需要通过“锁定”来搜索/ grep时。可能有很多垃圾。如果可以的话,值得通过pastebin发布。 –

回答

1

您如何测试?

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

容器将串行调用相同的SFSB实例。它应该这样做,如果它之前没有发生过,那么也许你有一些依赖于平台的部署描述符来禁用这种行为。

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

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

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

如果您在所有客户端之间共享一个SFSB实例,则可以将其从@Stateful更改为@Singleton。 Singleton EJB通过@ConcurrencyManagement@Lock注释给出明确的重入控制。如果你完全满意你的EJB的线程安全的,那么你可以用你的标记豆起来脱身:

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

我正在使用一个模拟器,它配置了几个终端(客户端)并连接到我的应用程序,密切模拟生产环境中发生的情况。这两个版本(EJB 2和3)都使用SFSB,唯一的区别是版本2使用的是基本的缓存系统,这不符合顺序处理(IMO)的要求。 –

+0

您有一个或多个所有客户端都可访问的SFSB? –

+0

是的,所有请求都由同一个SFSB处理。 –