为什么无状态EJB需要进行池化?

7
什么原因导致应用服务器池化无状态EJB?
我可以理解这样做有助于控制应用程序对入站调用的工作量,但这只能证明池化EJB作为FAÇADE与调用客户端一起使用是有益的。
对于内部EJB(那些没有暴露,只在内部调用以执行业务逻辑的EJB),池化它们是否有任何好处呢?而不是像Spring一样使用共享单个实例。
我可以想到至少一个缺点:高度使用的内部EJB可能会成为瓶颈。
2个回答

4

无状态会话Bean EJB不一定是线程安全的。它们可能持有资源,例如不能与多个线程同时共享的JMS会话,因此服务器将对它们进行汇集,以便可以同时为同一Bean提供多个请求( JMS资源也被池化,但我只是举例说明)。


如果它是无状态的,那么就没有状态会受到并发的威胁,因此不会出现竞争条件,所以它们是线程安全的,我错了吗?是的,我知道它们有一些状态,比如注入的资源,但也许它们不应该被称为无状态! :) 我接受这个答案是正确的。 - Mr.Eddart
@edutesoy 我同意你的解释。但是为什么要保持状态呢? - Sunny Gupta

3
我也想知道为什么无状态的EJB被池化。但我想知道的是为什么它们要被池化,而不是根据需要创建和销毁。实例可以被重用于不相关的请求,这显著增加了无状态bean的实现复杂性(这意味着您必须非常小心地使用实例字段),而我并没有看到任何显著的好处。
特别是,我没有看到任何性能上的好处。我在JBoss(6,如果我没记错)中浏览了无状态bean的实现,发现只有bean实例本身被池化;处理方法调用的管道每次使用时都会从头开始重新创建。这意味着唯一的性能节省是一次对象创建,这应该是非常小的时间量。唯一可能使其成为非微不足道的情况是,bean获取了重量级资源,并在调用之间保持了这些资源。但是,在这种情况下,bean实际上被用作一个辉煌的、管理不善的池;正确的解决方案是直接对资源进行池化!
现在,EJB已经存在了很长时间。当它们第一次出现时,对象创建是昂贵的,所以将它们池化是有意义的。但这些日子已经过去了。为什么在EJB3中没有放弃池化呢?

嗯,我想如果你有成千上万的并发请求,那么将它们汇集起来或者更进一步地,将它们创建为@Singleton(单例)是有意义的,只要你确定它们是线程安全的,而不是在内存中拥有成千上万个实例。 - Gonzalo Garcia Lasurtegui
1
如果Bean是线程安全的,那么单例模式是理想的选择。但如果不是线程安全的,则池化和一次性实例的内存负载将类似;池化实例实际上会给垃圾收集器带来更多的工作,因为它们的生命周期足够长以逃离幼儿园。 - Tom Anderson
那是一个很大的断言。我猜它取决于每个请求处理所需的时间,因此这些对象在池中花费的时间也不同。如果其中大多数可以随时使用,那么您可能会从创建/销毁中受益。这还取决于流量趋势等因素。在我看来,这是非常细微的分析 :) - Gonzalo Garcia Lasurtegui
我想这是因为无状态的EJB可以创建其他资源,例如连接和实体管理器,这些资源可能很昂贵。但是,如果您想要每个请求重新创建和丢弃的bean,难道没有设置一些可以实现此功能的范围吗? - Lii
@Lii:你可以使用CDI bean来实现,使用@RequestScoped注解。但是据我所知,你不能使用EJBs来实现。虽然你可以将@RequestScoped对象注入到无状态的EJB中(参见https://dev59.com/Ymoy5IYBdhLWcg3wL7L1),因此你可以将任何昂贵的资源推送到这样的对象中,以便及时清理它们。 - Tom Anderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接