2008年12月2日星期二

JavaEE_003: EJB3.0 性能调优 (摘录+整理)

Java EE应用中导致性能问题的罪魁祸首就是远程调用,这是分布式应用不可避免的问题。
分布式应用是运行在多个VM(Web容器、Servlet容器、EJB容器、数据库...)中的,这些VM可能分布在不同的机器上,即使在同一台机器上,也需要在不同的VM之间通讯。

1. 使用会话外观(Session Facade)访问实体(JPA实体或实体Bean)
直接访问实体的效率相当低下,需要经过:存根、骨架、Marshaling/Demarshaling、网络调用、EJB对象拦截器。

2. 如果客户端和EJB组件运行在同一个JVM中(如Web客户端),使用本地接口。
本地接口避免了按值传递对象,而是按引用传递对象(省略了序列化和反序列化的过程)。
本地接口虽然避免了远程调用的开销,但与同一个JVM中两个普通Java类之间的通讯相比,客户端还是要通过EJB 容器来调用EJB对象。

至于远程接口,一般只用在如下场合:
(1)需要通过远程访问(比如 远端Web客户端,独立的Java客户端)。
(2)使用独立的Java客户端测试EJB组件。
(3)集群环境,使用远程接口选择更多。比如为了负载均衡、容错。

3. 区分哪些是EJB特定的资源,哪些是独立于EJB的资源。
(1)EJB特定的资源:仅供特定EJB对象的EJB实例使用。
在创建(@PostConstruct)或激活(@PostActivate)EJB实例时获得该资源;
在销毁(@Remove、@PreDestroy)或挂起(@PrePassviate)EJB实例时释放该资源。
(2)独立于EJB的资源:供多个EJB对象的EJB实例使用,创建一次即可,多次重复使用。

4. 无状态会话Bean调优
(1)调整实例池大小:最小值满足系统正常运转,最大值满足系统高峰期运转。设置过大,浪费资源;设置过小,需要频繁创建和销毁大量对象。
(2)有效缓存资源:Just-in-Time策略,需要时才从连接池及时获取连接,用完后立即归还给连接池。

5. 有状态会话Bean调优
(1)调整实例池大小:某些EJB容器事先会创建实例化的、但未同客户绑定的、不含有会话状态的Bean对象。当需要时,EJB容器会从池中取出Bean对象,并初始化它,然后将它绑定到特定客户上。如果EJB容器提供了这类池,可以对池进行调优。
(2)调整缓存大小:当客户并发数超过了有状态会话Bean实例的上限时,EJB容器会强制缓存(挂起)一些有状态会话Bean实例,以便让腾出的有状态会话Bean实例服务其他客户。某些EJB容器支持不同的挂起算法(LRU、FIFO、NRU);还允许指定有状态会话Bean实例空闲多少时间后,挂起它;以及被挂起的有状态会话Bean实例多长时间内未激活,删除它。
(3)有效控制序列化:序列化会消耗CPU和I/O资源。反序列化(激活有状态会话Bean实例时),同样耗费资源。我们可以用Java transient关键字显式告诉EJB容器不要序列化哪些信息。

6. 实体调优
(1)调整实例池大小:调整原则与无状态会话Bean相同。
(2)调整缓存大小:调整原则与有状态会话Bean相同。
其它缓存建议:
(i)为经常使用的实体提供较大缓存,为很少使用的实体提供较小缓存。
(ii)将缓存大小和实例池的最大值设为一样。
(iii)实体的实例池和缓存大小通常都比无状态和有状态会话Bean大得多。例如:一个会话Bean一个finder方法就会返回大量的实体。
(3)使用延迟装载:客户不需要访问实体的所有数据时,可以考虑延迟装载。
(4)选择正确的事务语义。
(5)选择正确的事务隔离级别。
(6)获取大量数据时,建议使用会话Bean + JDBC,不要使用实体。
(7)为Entity Manager 选择合适的RDBMS驱动。
(8)选择正确的Statemant接口。

7. MDB调优
(1)调整实例池大小:调整原则与无状态会话Bean相同。
(2)JMS相关调优。

没有评论: