服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

详细介绍构建高性能j2ee应用的十个技巧

构建高性能的j2ee应用不但需要了解常用的实施技巧。下面介绍最常用的10种有效方法,可帮助架构设计师们快速成为这方面的专家。

java性能的基础―内存管理

任何java应用,单机的或j2ee的性能基础都可归结到你的应用是如何管理内存的问题。java的内存管理包括两个重要任务:内存的分配和内存的回收。在内存的分配中,目标是要减少需要创建的对象。

内存回收是导致性能下降的普遍原因。也就是说,内存中的对象越多,垃圾回收越困难。所以我们对创建对象的态度应该越保守越好。

在j2ee应用中常见的两个内存有关的问题是:游离的对象(也被称为内存泄露)和对象循环(指大量频繁创建和删除-在java中体现为解除引用---对象)。

我们应注意确保所有可到达的对象实际是活的,即这些对象不但在内存中,而且也要在执行的代码中是存在的。当对象在应用中已经没有用了,而我们却忘记了删除对该对象的引用时,游离的对象就出现了。

我们知道垃圾回收会占用cpu时间。短期对象的大量创建增加了垃圾回收的频率会造成性能下降。

不要在servlet中实现业务逻辑

在构建j2ee应用时,架构工程师通常会使用到j2ee的基本部分――servlet。如果架构师不使用session beans, entity beans, 或 message beans, 那么改进性能的方法就很少。只能采用增加cpu或更多的物理服务器等方法。ejb使用了缓存(cache)和资源池等方法可以提高性能和扩展性。

尽可能使用本地接口访问ejb

在早期的j2ee (遵循ejb1.x规范)应用中,访问ejb是`通过rmi使用远程接口实现的。随着ejb2.0的出现,可以通过本地接口访问ejb,不再使用rmi,在同一个jvm中使用远程方法已经少多了。但是现在还是有一些使用ejb1.x实现的应用和不知道使用本地接口的一些ejb新手。为说明这点,我们作个比较:

1、客户端应用调用本地stub

2、该stub装配参数

3、该stub传到skeleton

4、该skeleton分解参数

5、该skeleton调用ejb对象

6、ejb对象执行容器服务

7、ejb对象调用企业bean实例

8、企业bea执行操作

9、执行组装/分解步骤然后返回

与远程接口处理相比较,本地接口的ejb方法是:

1、客户端调用本地对象

2、本地对象执行容器服务

3、本地对象调用企业bean实例

4、企业bean实例执行操作

5、没有其他返回步骤!

如果你不需要从远程的客户端访问一个特殊ejb,就应该使用本地方法。

在实现session bean的服务中封装对实体ejb的访问

从servlet访问实体ejb不但效率低而且难于维护。使用session facade(会话外观)模式可把对实体ejb的访问封装在会话ejb中,在该会话ejb中通过使用本地接口访问实体ejb而避免过多的远程调用。

这项技术会有额外的性能和扩展方面的好处,这是因为会话和实体ejb可以使用缓存和资源池技术来进行改进。另外,由于负载的需要,会话和实体ejb可被扩展部署到其他硬件设备上,这比将servlet层复制扩展到其他硬件设备上要简单的多。

尽量粗粒度访问远程ejb

当访问远程ejb时,调用set/get方法将产生过多的网络请求,同时也导致远程接口处理的过载。为避免这种情况,可考虑将数据属性集中在一个对象中,这样通过一次对远程ejb的调用就可以传递所有数据。这项技术就是数据传输对象(data transfer object)模式。

优化sql

j2ee的架构设计工程师和开发人员通常不是sql专家或经验丰富的数据库管理员。首先应该确保sql使用了数据库提供的索引支持。在某些情况下,将数据库的索引和数据分开存放会提高性能。但要知道,增加额外的索引可以提高select性能但也会降低insert的性能。对于某些数据库,关联表之间的排序会严重影响性能。可以多向数据库管理员咨询。

避免在实体ejb中过多执行sql

有时候,通过实体ejb访问数据会执行多个sql语句。根据j2ee 规范,第一步,将调用实体bean的find(发现)方法;第二步,在第一次调用实体ejb的业务方法时,容器会调用ejbload()从数据库中获得信息。

很多cmp(容器管理持久性)在调用发现方法时就缓存了实体数据,所以在调用ejbload()时就不再访问数据库了。应该避免使用bmp(bean管理的持久性)或者自己实现缓存算法避免二次访问数据库。

使用fast lane reader 模式访问只读数据

j2ee应用经常要以只读方式访问大量长时间不变的数据,而不是访问单个实体,例如浏览在线产品目录。在这种只读情况下,使用实体ejb访问数据会导致严重过载并且实现很麻烦。实体ejb 适合于对单个实体的粗粒度访问,访问大量的列表只读数据时效率不高。不管是使用cmp还是bmp,一定需要编写代码操作多个实体ejb及其关联。这将导致访问多个数据库并存在大量的也是不必要的事务开销。

利用java messaging servce(消息服务)

j2ee规范在jms中提供了内置的异步处理服务。当涉及到系统需求时,应该了解在什么情况下应该采用jms进行异步处理的设计。一旦确定要执行一些异步处理,那么同步处理的任务就应该越少越好,将数据库密集的操作安排在稍后的异步处理中完成。

缓存jndi lookup查找

很多操作在进行jndi查找时要消耗大量资源。通常应该缓存jndi资源避免网络调用和某些处理的过载。可以缓存的jndi查找包括:

ejb home interfaces

data sources

jms connection factories

ms destinations/topics

一些jndi包实现了缓存功能。但是调用对ejb主接口的narrow方法时,这种功能作用有限。缓存查找的设计应该使用共享的intialcontext 实例,尽管构建它很麻烦。这是因为需要访问多种数据源,包括应用资源文件jndi.properties,系统属性的各项参数,传入到构造函数的各项参数。

扫描关注微信公众号