级别: 中级 Yan Fang Rao, 高级研发工程师, IBM Ru Fang (fangru@cn.ibm.com), 研发工程师, IBM Dr. Zhong Tian (tianz@cn.ibm.com), 高级架构师, IBM Eoin Lane (eoinlane@us.ibm.com), 高级解决方案工程师, IBM Harini Srinivasan (harini@us.ibm.com), 软件工程师, IBM Timothy Banks (tim_banks@uk.ibm.com), 软件工程师, IBM He Lei (heleihl@cn.ibm.com), 高级软件工程师, IBM
2006 年 9 月 04 日 缓存中介位于服务提供者和服务使用者之间,因此可为一个解决方案中存在多个服务提供者和服务使用者的情况带来好处。本文将提出一个缓存中介模式,可以将其作为可重用解决方案,从而加速采用消息传递中间件作为通信通道的面向服务的体系结构(Service-Oriented Architecture,SOA)环境中的服务响应。
引言
性能是面向服务的体系结构 (SOA) 环境中的一个重要的考虑方面。在很多实际情况下,缩短此类环境中开销很大的远程服务调用的响应时间都是一项关键的挑战。缓存广泛用于提高性能,已成功地应用于很多解决方案中来解决性能问题。本文提出了一个缓存中介模式,可以将其作为可重用解决方案,从而加速采用消息传递中间件作为通信通道的 SOA 环境中的服务响应。此模式中的缓存驻留在服务提供者和服务使用者间的消息传递中间件上。与传统设计模式不同,此模式更趋向于基础设施层,利用的是消息传递中间件提供的现有功能。
上下文
在 SOA 环境中,服务提供者和请求者彼此是松耦合的,分布在整个网络中(既可能在组织内,也可能跨越组织边界)。性能是此类分布式环境中的一个重要因素。例如,XML 广泛用作 SOA 中的服务提供者和使用者的消息格式。XML 消息的打包和解析会在两端都带来额外的开销。因此,就响应时间而言,Web 服务调用比其他类型的远程过程调用的开销更大。在很多实际情况下,缩短此类环境中开销很大的远程服务调用的响应时间都是一项关键的挑战。异步消息传递被广泛认为是 SOA 环境中(此类环境中,服务提供者和使用者可能分布在 Internet 上的不同位置)一个有效的通信通道。与直接的 SOAP over HTTP 之类的通信通道相比,消息传递中间件提供了服务提供者和使用者间的受控制中介消息交付。消息中间件中的中介提供了消息转换、日志记录、路由等中介功能。此类经过中介的服务调用的性能还进一步受到其他会带来干扰的消息中介的影响。
消息中间件支持多种消息传递范例:请求-响应、发布-订阅和单向方式。本文将重点讨论服务提供者和使用者间的请求-响应消息传递范例。
问题
由于冗长的 XML 消息有效负载和打包与解析 XML 所带来的额外开销,因此性能是 SOA 环境中的一项关键服务质量限制因素。将消息传递中间件作为服务提供者和使用者间的通信通道时,性能还将进一步受到其他会带来干扰的消息中介的影响。
对大多数生产环境而言,提供较好的性能是一项关键性的挑战。采用消息传递中间件作为通信通道时,缩短服务响应时间是 SOA 环境中的基本问题。
SOA 环境中的关键方面
在此类情况下的关键方面通常包括:
- 性能:SOA 环境中的服务响应时间在大多数生产环境中扮演着关键角色。服务提供者的响应时间会随着请求的大小和频率的增加而延长。而消息传递中间件中会带来干扰的中介则会进一步加剧这个问题。
- 加速多个服务提供者和使用者:消息传递中间件驻留在服务提供者和服务使用者之间。而采用此模式的用户希望能加速一个解决方案中多个服务提供者的响应和多个服务使用者的请求。消息传递中间件中会带来干扰的中介则进一步加剧了这个问题。
- 利用现有缓存解决方案,而不从头构建缓存。
解决方案
此解决方案要通过在消息传递中间件中缓存服务响应消息来缩短服务响应时间。当使用了完全相同的请求消息时,消息系统将从缓存中检索对应的响应消息,并将其直接返回给服务使用者,而不必将请求消息转发给服务提供者。这样可以消除开销很大的远程服务调用,从而改进服务响应时间。在连接到 SOA 环境的消息传递中间件中,多个服务提供者和使用者可以连接到同一个消息传递中间件。与服务器端或客户端的缓存不同,中介缓存驻留在中间的通信通道中。因此,在消息传递中提供缓存解决方案可以加速位于不同位置的多个服务使用者的服务请求速度,同时也能给多个服务提供者带来相应的好处。
此解决方案基于“Enterprise Service Bus : Making SOA real”(IBM Systems Journal,第 44 卷,2005 年第 4 期)一文建议的 ESB 缓存模式方案(这篇文章描述了如何缩短 ESB 环境中的服务响应时间,请参阅图 1)。企业服务总线(Enterprise Service Bus,ESB)是消息传递中间件的关键元素。在此缓存方案中,当缓存中介在缓存中发现服务请求的响应时,会将所缓存的响应直接返回给消息请求者。如果未在缓存中发现这样的项,则会将请求转发到服务提供者,服务提供者将随后返回路由回消息请求者的响应。同时,缓存中介将缓存此响应消息。
图 1. ESB 缓存模式
图 1 是根据 Enterprise Service Bus: Making SOA real
绘制的。
进一步分析后,会发现缓存中介模式需要解决两个具体的设计挑战:
挑战 1:在异步消息环境中表示请求和对应的响应
可以将缓存直接视为缓存项(键、数据)的集合。数据在缓存中通过其键标识。缓存类可以为一个基本方法“Object hitCache(Object key)”,该方法将根据键返回对应的数据,并根据特定缓存刷新策略将缺少的新数据放入缓存。
缓存需要标识请求和对应的响应,以加速服务响应。请求数据用于生成缓存键,响应数据作为缓存项中的缓存数据存储在缓存中。因此,当向服务提供者发出相同的请求时,可以直接从缓存中检索响应数据。服务器端缓存和客户端缓存都可以方便地从一个调用中标识请求及其响应。例如,hitCache 方法可以与以下所示类似:
清单 1. hitCache 方法
public Object hitCache(Object request) {
Object key = generateKey(request);
Object response = this.cache.get(key);
//cache is missed, invoke the service and get response data
if (response == null){
response = this.service.invoke(request);
this.cache.add(key, response);
}
return response;
}
|
在消息传递环境中,调用与此不同。请求消息和响应消息是分开交付的。图 2 描述了此行为。在此环境中,消息中介采用异步方式独立工作。请求消息和响应消息将分别触发请求消息中介和响应消息中介。例如,在 IBM® WebSphere® Application Server 的 ESB 实现 Service Integration Bus (SIBus) 中,消息中介处理程序实现为 Enterprise Java™ Bean (EJB)。请求中介或响应中介都不能按照上面所示的方法标识相同 hitCache 方法调用中的请求消息及其对应的响应消息。请求中介和响应中介独立工作,即,当响应消息触发响应中介时,请求中介可能为非活动状态。中介缓存模式要求使用特殊的设计来处理此问题。
图 2. 消息传递中间件中的中介行为
挑战 2:利用现有缓存机制
模式设计需要考虑的另一个问题是如何将现有缓存解决方案作为缓存机制的基础。缓存是一项广泛用于提高应用程序性能的技术。各种软件产品中设计和实现了各种缓存来提高应用程序响应,如 JbossCache、SpiritCache、Websphere Application Server 的 Dynamic Cache Service 等。缓存中介模式的设计需要允许容纳各种不同的基础缓存解决方案,而不是完全从头构建缓存。
详细的解决方案将在以下部分进行介绍。
结构:由一个缓存实现耦合的两个缓存中介
图 3 描述了缓存中介模式的结果。可以将此结构描述为由一个缓存实例耦合的两个缓存中介。正如前面提到的,中介指消息传递系统中的消息处理程序。它将执行日志记录、路由、消息格式转换和其他需要对消息执行的任务。通过使用由单个缓存实例耦合的两个缓存中介,在两个缓存中介间实现协作,可以解决相关请求和响应消息的标识问题。
图 3. 缓存中介模式结构
类关系图
图 4 中所示的类关系图显示了该模式中涉及的缓存中介的详细结构。
在类关系图中,ServiceClient 接口用于生成请求。Service 接口将根据来自 ServiceClient 的请求产生响应。这两个接口使用 Mediation 类,此类是 Service 和 ServiceClient 间的通信通道。这是具有消息传递中间件的 SOA 环境中的典型调用方式。
Mediation 类由 RequestCacheMediation 类和 ResponseCacheMediaton 类组成,实现了 Cache Mediation Handler 接口。正如前面所介绍的,缓存通常由一组缓存项组成。缓存项组织为键 和数据,其中键用于标识数据。Cache Mediation Handler 接口从请求和响应消息生成键和数据,然后通过调用 Cache 接口提供的 hitCache(), insert() 和 remove() 操作。Cache 接口由 CacheImpl 类实现。此处的 hitCache() 操作可以确定是否已经存在具有给定键的缓存项,insert() 操作将一个新缓存项传入到缓存中,而 remove() 操作用于根据给定的缓存键删除缓存项。
图 4. 缓存中介模式类关系图
序列关系图
模式参与者间的协作在图 5 中描述。服务提供者、缓存中介和服务使用者间的交互如下:
- 首先,服务使用者向服务提供者发送一条请求消息。消息传递中间件将消息路由到服务提供者的目的地。
- 当消息达到目的地时,附加到目的地的请求中介可以访问消息内容并对消息执行一些操作。缓存请求中介基于请求消息生成缓存键,并在缓存中搜索响应。
- 如果找到匹配响应,缓存请求中介则将该响应消息立即返回给服务使用者。否则,会将请求消息发送到服务提供者,并将向缓存中插入一个新缓存项(使用所生成的缓存键)。
- 当服务提供者返回响应消息且消息传递中间件将响应路由到服务使用者时,将调用缓存响应中介。
- 缓存响应中介将标识缓存中相关的请求消息的缓存项,并使用响应消息更新缓存项,从而完成缓存请求中介创建的缓存项。
图 5. 缓存中介模式中的参与者行为
适用性
-
通信通道:如果希望应用此模式,服务提供者和使用者间的通信通道需要为消息传递中间件。
-
缓存位置:缓存与驻留在消息传递中间件中的缓存中介关联。服务提供端或服务请求端的缓存不适用此模式。
-
调用样式:要应用该模式,调用样式应为请求-响应样式,应根据一个请求生成一个响应消息。发布/订阅等其他调用样式不适用此模式。
-
服务提供端容错:缓存模式要求对服务进行加速,因此可以容许完全相同的请求不交付给它,且消息传递中间件可以缓存响应。这其中有几个值得注意的特点:服务不是事务型的;数据更改频率不高或数据过期时间并不短;数据审计策略允许存在不送达服务提供端的请求数据;数据保密策略允许数据缓存在通信通道中。
结果
-
行为:消息传递中间件的行为已更改。它将主动更改请求消息的路由路径,将缓存的响应消息发送回服务使用者。服务提供者并不会接收每条请求消息。
-
数据:由于消息传递中间件中使用了缓存,因此响应消息可能会不是最新的。由于缓存而导致的数据过期需要得到缓存用户的理解,可以通过使用缓存数据刷新策略建议缓解。
-
性能:缓存将缓存请求和对应的响应消息,从而提高服务的响应能力。不过,缓存具有相应的开销。消息中介需要额外的开销来访问消息的有效负载和存储缓存消息。
使用缓存时的注意事项
-
消息相关:消息传递中间件需要提供消息相关机制来将请求与对应的响应消息相关。相关可以由消息传递中间件自动完成,或由服务提供者使用消息传递中间件提供的相关性 API 来进行。
-
消息标识:消息中间件可以提供更快的消息标识选项,以便模式用户能选择相应的消息标识来进行缓存项标识键生成和比较。
-
基础缓存:缓存中介模式并不是用于通用缓存设计的设计模式,而将利用消息传递中间件或其他缓存系统提供的现有基本缓存功能。在我们的参考实现中,我们使用了 Websphere Application Server 的 Dynamic Cache Service 作为此模式的基础缓存。
相关模式
请求端缓存模式:缓存中介模式最初源自一项调查,此调查的目的是为了确定请求端缓存模式是否可用在消息传递中间件上下文中以及如何使用。它还尝试解决类似的问题和解决不同缓存设计(缓存驻留在请求端)。
已知用途
此模式可以用于服务集成总线(SIBus,ESB 的一个实现)。SIBus 在 IBM WebSphere Application Server Version 6 上实现,可以利用 IBM WebSphere Application Server Version 6 提供的动态缓存来缓存请求和响应消息对。在此用例中,缓存策略(如数据验证策略)是由 IBM WebSphere Application Server Version 6 提供的支持,这意味着缓存策略在 IBM WebSphere Application Server Version 6 中的某些部署文件中配置。
结束语
模式是特定抽象级别的解决方案,用于解决在不同上下文中重复出现的问题。本文以 Gamma 等所著的“
Design Patterns: Elements of Reusable Object-Oriented Software
”一书中给出的模式框架为基础,提出了 SOA 环境中一种新模式,即缓存中介模式。与服务器端和客户端缓存不同,缓存中介驻留在服务提供者和服务使用者之间,因此可以为一个解决方案中包含多个服务提供者和服务使用者带来好处。
参考资料 学习
获得产品和技术
讨论
作者简介  | |  | Fang Yan Rao 是IBM 中国研究院的高级研发工程师。她于 2000 年获得了西安交通大学的计算机科学硕士学位。Rao 目前的研究重点是 SOA。 |
 | |  | Ru Fang 是 IBM 中国研究院的研发工程师。她于 2005 年获得了西安交通大学的计算机科学硕士学位。自从加入 IBM 后,Fang 一直在从事 SOA 方面的研究工作。 |
 | |  | Zhong Tian 在 IBM 中国开发中心的 Lab Based Services 担任高级架构师。他于 1995 年获得了复旦大学的计算机科学博士学位。他有大量的客户协作经验,曾参与过很多大型制造业、银行业和运输业解决方案的设计和开发。他一直在从事 SOA、业务流程建模及集成和电子商务领域的工作。Tian 博士是中国开发中心的解决方案开发首席架构师。 |
 | 
|  | Eoin Lane 博士是 IBM Enterprise Integration Group 的高级解决方案工程师。他在其中负责 SOA Pattern 工作。 |
 | |  | Harini Srinivasan 是 IBM Enterprise Integration Group 中的 SOA Design Requirements 团队的成员。她感兴趣的领域包括 Web 和 SOA 应用程序性能分析、用于构建 SOA 解决方案的模型驱动的开发方法、应用程序和运行时的设计与优化。在加入 IBM Software Group 的 EIS 团队前,她在 IBM T.J Watson Research Center 的 Software Technology 部门担任助理研究员。
|
 | |  | Tim Banks 是 IBM Software Group 的软件工程师。他曾从事 CICS 事务处理系统的通信机制方面的工作,从中获得了大量的客户协作及大型机工作经验,他最近一直在从事大型系统(包括网格)的 Web 服务标准及大型系统中的服务集成模式(有时也称为 EJB 技术)方面的工作。 |
 | |  | He Lei (Joyce) 是位于中国北京的 IBM Enterprise Integration Design Center 的高级软件工程师。她于 2003 年取得北京航空航天大学的计算机科学硕士。自从加入 IBM 以来,He 一直在从事 Grid Computing Group of CSDL 的 China Grid 项目方面的工作,并参与了若干 EIS 设计中心的客户项目。她目前在进行 IBM SOA 支持工具方面的工作。 |
对本文的评价
|