站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2EE 专题改善Java企业级应用的可用性

改善Java企业级应用的可用性

摘要: 本文主要讨论HA(高可用性)环境中的特性。然后会讨论一些专门针对HA环境的设计方案。最后介绍一些应用级(即使应用不会布署在HA环境中)的改善可用性的最佳实践。
设计高可用Java企业级应用的最佳实践

摘要

如今在7*24商业领域中,高可用性是网页应用的最重要需求。专门设计的底层架构可以增加网页应用的可用性,底层架构本身不会使应用更可用。本文重点在于如何设计高可用的应用。作者讨论来自于保证100%可用的J2EE应用设计中的一些最佳实践。

版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:Ajay Raina etc..;xMatrix(作者的blog:http://blog.matrix.org.cn/page/xMatrix)
原文:http://www.javaworld.com/javaworld/jw-12-2005/jw-1226-jee.html
译文:http://www.matrix.org.cn/resource/article/44/44227_Availability+Enterprise.html
关键字:Availability;Enterprise

对一个在线商务站点来说,需要7*24的服务时间。这就是说对商务网站来说保证不间断的运行是最重要的事。任何差错都会导致客户不能访问商务站点提供的信息和服务。而这又会导致收入的损失和客户的报怨。

改善应用可用性的关键在于将应用放在专为高可用性设计的工作环境中。在基础框架中高可用性通常是通过各个级别的冗余来取得的。但为了更好的利用环境中内建的可用性能,应用设计者需要考虑事先考虑高可用性问题。需要注意的是一些应用设计上的选择可能在简单的环境中正常运行但在高可用环境中却是低效的。例如对一些不会布署在高可用性环境中的应用来说,某些设计方式可能会改善其性能。

本文主要讨论HA(高可用性)环境中的特性。然后会讨论一些专门针对HA环境的设计方案。最后介绍一些应用级(即使应用不会布署在HA环境中)的改善可用性的最佳实践。

HA环境

下面是两个典型的代表极端HA基础架构的主机环境示例。图1显示了一个完全布署在一个服务器上完整的J2EE环境。


Figure 1. Single-server hosting environment

在这种环境中,HTTP/J2EE/RDBM服务器完全共存于同一台物理机器上。这可能是最低效的J2EE环境了,而且也是最少容错的,因为可能只因为潜在的单点错误导致整个环境不可用。
另一种情况如图2显示。


Figure 2. High availability hosting environment. Click on thumbnail to view full-sized image.

这个布署环境由多个数据中心组成,通常在不同的地理位置,但是保持一致的软硬件兼容。几乎所有的服务都是冗余的。在这个环境中,每一个组件都驻留在分离的容错硬件上。这种地理上分离的数据下发环境依赖于数据和群集来同步所有的数据传送。
两个HA环境最重要的特性是:
1、 无单点错误:通过在环境中增加冗余避免单点错误。这个原则应用应用到所有软硬件层次。
2、 容错:在发生错误时,通过负载均衡动态地恢复服务到可用的服务器上。

设计利用基础架构中高可用性的应用

拥有HA基础架构并不意味着拥有高可用性的应用。如果应用没有考虑到利用基础架构中的高可用性,是不会拥有高可用性的。对这些类型环境的应用设计需要在设计和实现上作额外的考虑。

例如,如何在多个数据下发中心间共享会话信息或者如何同步到复制数据库中来提高终端用户的体验。下面的关于设计和实现的最佳实践将有益于利用HA基础架构和增加应用的可用性:
·使用只读JVM缓存:在典型的HA配置中,应用的几个实例同时运行在不同的应用服务器上,每一个服务器都有自己的JVM,因此在你更新本地缓存的数据时,更新只能被当前JVM知道,其他应用的实例不关心这次更新,这就是为什么你应该将JVM级的缓存作为只读的。但在存在跨越多个JVM的分布式缓存时是个例外。取决于你的应用服务器,你可以有不同的解决方案或者实现自己的RMI方案。
·考虑分布式HTTP会话:为了解决HTTP协议无状态的问题,应用需要靠HttpSession API来存储会话信息。在群集环境中,应用的多个实例运行在不同珠服务器上,在使用HttpSession时需要考虑下面几点:
o 实时地复制会话数据:既然你不知道哪个实例会处理会话中的下一个请求,会话数据应该实时地同步到群集中的所有服务器。这可以通过存储会话数据在数据库中并实现数据库级别的复制就可以了。一些应用服务器如WebSphere, WebLogic提供了更快的内存会话复制特性,如果你使用这类应用服务器,你就可以考虑一下了。
o 序列化会话对象:存储在分布式会话中的对象需要实现java.io.Serializable接口。实现这个接口确保数据可以被无线地传送到群集中的每一个服务器实例了。一个好的方法是强制使用自定义方法如addObjectToSession(String key, Serializable value)来代替HttpSession.setAttribute (String key, Object value)。区别在于如果你调用addObjectToSession()方法时传递了非序列化对象,你会得到一个编译时错误。而你尝试复制保存在会话中的非序列化对象时,你得到的是运行时错误,而这会影响用户体验。
o 实现容错性:让应用知道冗余基础架构资源的存在,如果需要的话建议通过动态运行时切换来实现。例如,如果应用使用消息服务器而且每一个数据中心有一个消息服务器,让给定的数据中心上运行的应用知道在另一个数据中心上的服务器可以作为错误的备份。
o 在测试时要有创造性:通常你会在与布署环境一致的环境中测试应用。但在实际中,一个HA产品环境需要比测试环境更多地时间来建立。因此,完全地镜像产品环境是代价高的。在这种情况下,你可以通过创造性的测试来弥补相应环境的缺少。你可以使用两台工作站来模拟HA环境。然后你应该考虑下面的测试场景:1、在你关闭一个数据库时应用是否正常?2、在一台本地机没有响应时应用是否能成功从另一台机器连接LDAP服务器?这些类型的测试可以协助测试应用的容错性。


在应用级的改善可用性的最佳实践

到目前,我们主要还是强调可用性的重要性及如何使基础架构具有更好的可用性,及如何在HA环境下考虑应用的设计。接下来,我们会讲一些在应用级别的改善可用性的设计技巧。

自主的应用资源管理
避免在应用中硬编码外部资源是一个通用的实践。通常,外部资源是在应用启动时加载到内存中并作为只读资源被应用使用。外部资源的典型例子如应用的属性文件(包含可翻译的文字串)或者是与应用相关的配置信息。
通常,外部资源的改变并不会反映到应用的内存中。只有重启应用才能使被改变的外部资源生效,而这会临时中断应用的服务。在这种情况下,应用的可用性与他的外部资源的更新频率直接相关。

一个有效的改善应用的可用性的方式是自动重新加载外部资源,而不需要重启应用。下面是自动应用资源管理工具的主要特性及其相关设计和实现的指引。

资源管理器:
1、 周期地检查外部资源并在其修改时重新加载。检查的周期依赖于业务需求。
2、 提供一种类似用户初始化式的显式加载,这可以通过浏览器触发;例如重新加载servlet可以处理这个需要并进行重新加载资源。
3、 使用线程安全的重新加载来确保应用即使在重新加载的过程中再次获取当前配置数据。记住访问正在被重载的资源可能导致数据的不一致性。
4、 支持各种资源类型,如属性文件和XML文件
5、 可以使用开源工具,如Quartz Scheduler和Apache Commons Configuration。
一种资源管理的样例设计是保存两份资源内容,在一份资源正在更新内存时,应用依旧可以查询到任何需要的信息,这保证了应用的可用性。图3是这种设计的图例:


Figure 3. Sample resource manager model. Click on thumbnail to view full-sized image.

在应用初始化时,资源管理器会加载所有定义在外部属性文件中的资源文件。Resource接口被用来实现创建一个相对于每一人应用资源唯一的Resource类型。ResourceContainer类型包含一个ResourceController对象的注册表引用,第一个对象包含两个特定的Resource类型,但同一时间只有一个对象是可用的。资源数据通过ResourceContainer接口的get()方法来访问。当应用处理一个请求时,ResourceController对象查询当前可用的Resource实例。在一次自动刷新或显式用户初始化刷新时,ResourceController重新载入当前不可用的实例并将其指定为可用对象,同时使原来可用的对象无效。
用这种方式,资源管理器工具确保应用资源是最新的完整的并且以线程安全的方式来自动更新,而不需要重启应用,这样就提高应用的可用性。

优雅的错误处理
保证应用可用性的一个重要方面是避免错误。但如果错误确实发生,那么给用户相对差一些的体验也比给一个错误面页强提多。
有很多错误处理的优雅方案:
1、 在错误页面使用缺省内容:定义各种不同场景下的缺省页面。缺省行为的使用很大程度下依赖应用和功能在错误时执行的方式。例如,在我们的一个应用中,我们可以定义通用的访问页面人作为错误页面。
2、 在错误发生时给出警告。
3、 在应用容器级别配置捕获所有错误。这可以通过在web.xml中定义错误页面来完成。

监视应用状态
定义一些测试案例来验证应用的健康状态是个好主义。这些测试案例可包含的servlet中通过手工或自动工具来执行。
一些监视应用健康状态的方案如下:
1、 可以通过低优先级的线程/工具来报告应用的健康状态和发送相关警告。
2、 在应用中嵌入健康监视功能。这种类型的监视服务可以通过外部脚本在应用出现问题时通知管理员。例如,可以在内存不足时发送JVM将要内存溢出的警告。

通过定时的方式来激活外部服务
如果应用有外部依赖,实现对超时的控制有助于处理外部服务没有响应的情况,在超时的情况下,如果允许建议使用缺省的行为,但在面向事务的应用中可能会有什么困难。

在软件开发过程增强质量控制
应用的可用性关键在于应用程序的质量,而这可以通过在开发团队中开展一种“可用性思考”文化来提升。通常,采用强调质量的开发实践可以帮助开发健壮/容错/高可用的应用,具体如下:
1、 成对编码:可以改善代码的质量
2、 代码规范:提升代码质量及使最佳实践
3、 自动测试:有用的回归工具
4、 通过IDE内建的工具检查代码质量

小结

要想在因特网上真正地成功,应用必须能够7*24不间断地处理服务请求。为了取得高可用性,公司通常会在基础框架上投资来得到多级别的冗余。但只在基础框架上投资是不够的。其上的应用必须设计成能够利用基础框架的特点。此外,设计的最佳实践也可以改善应用的可用性,即使应用不是布署在HA环境中。

关于作者
Ajay Raina是IBM的应用架构师,有多年的JEE产品应用的架构/设计/开发的经验。他在IBM研究院/软件组/IBM.com领导过多个项目。擅长JEE, WebSphere, DB2和面向对象应用开发,及敏捷软件方法学。
John Jimenez是IBM的高级IT专家,有10年以上因特网相关经验。其兴趣主要在面向对象设计,模式,敏捷软件方法学及因特网技术。
Govind Nishar是IBM Corporate Webmaster团队的咨询软件工程师。在JEE应用的设计/实现和基于Java的网页服务上有超过5年的经验。最近,他协助在团队中率行实行敏捷软件方法(主要是XP)。
Ning Yan是IBM的软件工程师。他是最新的软件工程方法学和网页技术的传道者并解决实际的业务问题。

资源
·讨论HA基础结构的红皮书:“IBM WebSphere V5.1的性能/可伸缩性/HA”:http://www.redbooks.ibm.com/abstracts/sg246198.html?Open
·“HA设计”:http://www.dmreview.com/editorial/dmreview/print_action.cfm?articleId=1001155
·“网页耕种:可用性和可伸缩性”:http://www.informit.com/articles/article.asp?p=27581&rl=1
·WebLogic Server群集介绍:http://www.weblogic.com/docs51/cluster/overview.html
Seven Steps to Highly Available Systems (Sun, 2003): 通向HA系统的七个步骤
http://www.sun.com/emrkt/innercircle/newsletter/feature0203.html

↑返回目录
前一篇: Spring XML配置十二个最佳实践
后一篇: 深入理解SKIP_PAGE, EVAL_PAGE