IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere  >

任务:消息: 接纳 WebSphere MQ 社区中的文化变化

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

英文原文

英文原文


级别: 初级

T.Rob Wyatt, 高级管理顾问, IBM

2008 年 12 月 08 日

Journal icon WebSphere® MQ 社区很长时间以来一直在使用相同的最佳实践,面对业内发生的所有变化,当今的基础处理模型已远远偏离了开发这些最佳实践时存在的模型。这种差异代表着重大的潜在风险,但是作为一个社区,我们现在有机会弥补这个差距,并让我们的最佳实践与当前采用的用例保持一致。

来自 IBM WebSphere Developer Technical Journal

在每个专栏中,“任务:消息”讨论的主题旨在鼓励您重新检查您对 IBM® WebSphere MQ 及其在您的环境中的作用的看法,以及为什么您应该定期地注意它。

WebSphere MQ 的文化遗产

在 WebSphere MQ 面世后的十五年间,用户社区中的持续对话产生了公共知识和最佳实践的文化遗产。这种集体智慧已在在线论坛、会议录、技术期刊和全世界数千家 IT 企业的私有文档存储库中积累起来。这些年来,它经过重新定义、提炼、调整和优化,其知识体系已达到了显著一致和持久稳固的程度。

这是一件好坏参半的事情。

在第一期“任务:消息”专栏中,我曾经写到,WebSphere MQ 的可访问性已在许多企业导致了对正式培训的不够重视,并且由此产生的技能差距经常导致中断。但是,这件事情的另一面在于,相同的可访问性——我们的最佳实践和公共智慧的遗产——降低了新用户进入 WebSphere MQ 的门槛,并提高了实现的总体质量。这些优点是 WebSphere MQ 社区培育这个集体知识系统的自然和强大的动机。事实上,该动机是如此的强大,以致该社区有时将不再需要理解、几乎没有价值并且在某些情况下实际上是破坏性的反模式的实践永久地保留下来。这说明了文化惰性原理——长眠的文化基因 (meme) 将保持长眠的趋势。





回页首


程度上的差异与种类上的差异

文化惰性随时间推移的结果在于,作为一个社区,与更新我们的知识体系相比,我们更擅长于向我们的知识体系添加新内容。当新的产品功能或用例出现时,人们往往去寻找与某些现有最佳实践相似的东西,并从那些现有最佳实践的基础上着手。如果结果行之有效而没有任何破坏性,它将成为文化结构的一部分,即使新的用例可能违反了作为原始最佳实践基础的基本假设。

如果新用例真的是旧用例的超集或扩展,那么此过程将产生合理和可靠的新最佳实践。这些种类的增量更改是程度上的差异:A 像 B,但是稍微复杂一点。

然而,对于种类上的差异,其中 A 一点也不像 B,并以预料之外的方式与 B 交互,文化对此的反应非常不同。这些更改不容易归类到现有的类别中,因此它们迫使我们质疑作为当前最佳实践基础的基本假设。它们预示着使我们的体系结构、我们的代码、我们的操作手册失效,最糟糕的是,使我们将偶然的知识替换为深入技能的能力失效。种类上的差异耗费资金。它们需要业务用例。它们发现愿意支持它们的拥护者非常少。

我们并不非常擅长于适应这些范式转换。它们常常假扮为增量更改被吸收到文化中。此过程在我们的实现中引入了潜在缺陷和漏洞,并以不断增加的潜在风险的形式积累。然后,当灾难性的破坏发生时,对于事情如何和为什么达到如此糟糕的地步,以及为什么事先没有警告,我们感到疑惑不解。这就是在文化上等价于铁锈的东西。曾经的“最佳实践”随着时间的推移而成为了简单的“实践”,并最终成为了反模式——初看起来不错但实际上是破坏性的实践。





回页首


客户端与绑定连接

深入回顾 WebSphere MQ 的古老历史,种类上的差异的一个示例是 MQSeries 客户端的引入。在连接的队列管理器端,API 调用相同,授权机制相同,因此普遍的实践是将客户端应用程序看作像是绑定模式的应用程序——但是具有额外的通道定义。在应用程序端,可以接受绑定模式的应用程序,并在客户端模式下运行而不做任何更改,在许多情况下,这就是确切的实际做法。

但是绑定和客户端模式是根本不同的,因为在客户端模式下,通道存在于应用程序和队列管理器之间。作为管理员和开发人员,我们希望将此通道视为到队列管理器的透明连接,但它不是。当两个队列管理器通过某个通道交换消息时,连接的两端由消息通道代理(message channel agent,MCA)管理,MCA 共用一种复杂的协议,该协议确保将持久消息序列化、硬化到磁盘,然后在从发送端删除之前由接收者加以确认。两个 MCA 进程管理各批消息,在失败之后自动重新同步,并根据需要提交或撤销工作单元,以保持数据的完整性。这与客户端应用程序形成鲜明对比,其中连接的一端是消息通道代理,另一端是应用程序代码。为了能够像队列管理器到队列管理器的通道一样可靠,客户端应用程序必须重复 MCA 的通道同步逻辑,以便从断开的连接中恢复。例如,如果连接在执行某个 COMMIT 操作时断开,则存在两种可能性:1) 连接在 MCA 接收到 COMMIT 之前失去,或者 2) MCA 处理了 COMMIT,但是无法将响应代码传输回应用程序。

在第一种情况下,MCA 从未看到该 COMMIT 调用,事务最终将被回滚。此时,在同步点下 PUT 的任何消息将从队列中删除,使用破坏性 GET 调用从队列读取的任何消息将回滚到队列上,并最终重新传送到应用程序

在第二种情况下,MCA 已对 COMMIT 采取了行动,但是未能传输响应代码,因此将不存在要回滚的事务。使用破坏性 GET 从队列读取的消息将从队列永久删除,任何 PUT 的消息将完成传输。

使事情复杂化的事实在于,待处理的事务将在同步点下保留不确定的一段时间,以等待 TCP 让套接字超时。此间隔可能为数秒,也可能为数分钟,具体取决于 TCP 内核设置。请将这与绑定模式下的断开连接做一下比较,后者几乎由队列管理器立即检测,然后回滚事务,通常是在几毫秒之内。在两种情况下,事务的结果在回滚事务之前都是不明确的,但是这种不明确性的持续时间在一种情况下为数毫秒,在另一种情况下可能长达数分钟。

用于在绑定模式下从断开的连接中恢复的应用程序代码对于立即协调事务状态和有序地继续处理具有合理的预期。客户端模式下的相同应用程序必须考虑到,在能够进行任何协调之前,事务可能在几分钟内保持未完成状态。如果事务具有严格的时效性,则上述的其中一种情况是可接受的,另一种情况是不可接受的,但是对社区中的许多人来说,这两种情况在功能上是等价的。

随着时间的推移,出现了某些用于客户端应用程序的新最佳实践,以处理断开连接的不明确结果。其中包括执行同步点下的所有 API 调用,在接口任一端编写应用程序代码来处理重复消息,以及在断开连接后重新发送 PUT 消息。这种情形并不是 WebSphere MQ 所特有的,事实上它是在 JMS 规范的 4.4.13 节中讨论的,其中陈述道:

如果故障发生在客户端于某个会话中提交其工作与 commit 方法返回之间,则客户端无法确定事务是已提交还是已回滚。当故障发生在 PERSISTENT 消息的非事务性发送与从发送方法返回之间时,也存在同样的不明确性。

处理这种不明确性是 JMS 应用程序的责任。在某些情况下,这可能导致客户端产生在功能上重复的消息。

由于会话恢复而重新传输的消息不会被视为重复消息。

(Java Message Service - Version 1.1。2002 年 4 月 12 日)

存在一个对立的学术流派,他们坚持认为客户端和绑定模式连接之间不存在任何差异。争论的焦点在于,绑定模式连接中的 MQRC 2009 CONNECTION_BROKEN 响应代码具有同样的结果不明确性,无论连接模式如何,应用程序都需要统一地处理这些不明确性。正如我所主张的,如果这真的是种类上的差异,则正确的方法将是以不同的方式设计客户端和绑定模式应用程序。另一方面,如果这只是程度上的差异,正如 JMS 规范所建议的那样,正确的答案是适当地设计客户端和绑定模式应用程序,以考虑到消息 API 调用的不明确结果。无论是哪种方式,问题在于主流的实践将其误解了!

只有在引入 MQSeries 客户端以后,断开连接的问题才浮出水面。到问题变得众人所知的时候,基于“失败事务的结果能够立即和可靠地检测到”的假设,“最佳”实践已经建立起来了。尽管 MQSeries 客户端违反了作为现有编码实践基础的用例,尽管随后开发了正确地对基础问题建模的竞争方法,但是到目前为止的主流实践仍然反映了原始模型,即其中不存在结果不明确性。





回页首


更全面的情况

断开连接问题只是其中一个示例,说明了 WebSphere MQ 文化如何倾向于固守既定的实践,即使是在那些实践已经过时或者显然被违反之后。我挑选此问题是因为它说明,尽管有在用户社区得到大量支持的更好地建模和更加可靠的方法的竞争,现在的文化基因仍然固守于被违反状态。

还存在许多其他示例,包括:

  • 备份策略:我看到过的大多数最佳实践文档,包括关于该主题的 IBM 红皮书,都建议备份队列管理器下的文件。此实践模仿并扩展了在文件系统级别备份应用程序及其配置细节的实践,当应用程序主要在绑定模式下连接到 MQSeries,并与 MQSeries 驻留在相同的服务器上,并且关闭所有一切来进行备份时,该实践是行之有效的。但是对于合并和虚拟化,当今的队列管理器没有维护时间窗口,并在任意数量的应用程序之间共享,其中许多应用程序是远程的。在队列管理器运行时对其进行备份决不是个好主意,虽然这种情况经常发生,有时还导致了不可用的备份。即使停止 WebSphere MQ 进行备份,将 MQ 备份与所有客户端应用程序的备份进行同步也是不可能的。万一要从备份中恢复队列管理器,对所有那些应用程序的影响在最好的情况下也是不可预测的。

  • 消除软限制:在开发新应用程序的过程中,偶然碰到诸如 MAXDEPTH 或 MAXMSGL 等软限制是相当常见的。通常的应对方法是取消这些值以消除“问题”。由于不需要添加代码和复杂性以处理这些限制,开发可以更快地进行。但是这种方法将软限制视为要消除的麻烦,而不是预期的有用工具。遇到这些软限制的应用程序可能会受到影响,但至少有机会敏感地响应问题。如果消除那些限制,队列管理器将冒着耗尽物理资源的更大风险。当达到这些硬限制时,整个队列管理器和所有已连接的应用程序都将停顿下来。与在第一时间提示更改的单个应用程序只会受到临时和隔离的影响相比,这种情况要糟糕得多。已编写的最佳实践文档中的参考资料通常对这种情况提出了正确的建议,但是社区的绝大多数人都忽略了该建议。

  • 名为 TO.<QMGR> 的集群通道:此实践在不存在重叠集群的少数情况下有效。现在集群已成为主流,重叠集群正在变得相当普遍。此命名约定确保在队列管理器参与的所有集群之间共享 CLUSRCVR 通道。在此配置中,一个集群中的维护必然影响任何其他集群的操作,因此我认为此实践是经典的反模式。一种更好的方法是使用诸如 <CLUSTER>.<QMGR> 等名称,它可以确保每个集群的专用通道。然而,产品手册仍然对 TO.<QMGR> 约定做了文档记录,因此该实践可能仍然会在未来一段时间得到广泛实施。

  • 远程连接的身份验证:对于客户端连接和来自其他队列管理器的通道,存在许多与身份验证相关的常用实践。典型的示例是这个经常重复的建议:WebSphere MQ Explorer 中授权错误的解决方案是将用户 ID 放在得到足够授权的本地组中。此方法的问题是假设存在的 ID 已经以某种方式经过了身份验证。事实上,WebSphere MQ 无论如何也不执行任何身份验证。身份验证被委托给操作系统(对于绑定模式的连接)或委托给通道安全出口(对于远程连接)。可以使用 SSL 对通道连接进行身份验证,但是除非存在出口,否则所获得的身份不会传播到 API 层。由于 WebSphere MQ 身份验证被如此误解,主流的安全实践几乎无一例外地集中于授权(setmqaut 命令)而忽略了身份验证。您可以运行您希望的所有 setmqaut 命令,但是如果没有身份验证,这些命令只能约束那些不需要担心的最诚实的人。如果忽略身份验证,能够访问网络且具有恶意企图的任何人都可以毫无问题地绕过已设置的任何授权。

这样的示例不胜枚举,不过我不希望迷失在这些示例中。我们必须将那些示例留给其他文章。我的观点在于,我们作为一个社区,在接纳文化变化方面原本可以做得更好。我们应该不时地重新审视我们的实践,并让基础的假设重新有效。然后,如果我们发现某个实践不再模仿现实世界,则应该对其进行更新。





回页首


展望未来

由于改变既定的实践是如此之难,有效的方法在于预先捕获错误。如果我们在新用例出现的时候擅长于区分种类上的差异和程度上的差异,并擅长于适应真正不同的用例,那么我们的社区成员即使遵循了所有的“最佳”实践,遇到的突然、意外并且有时是灾难性的中断也将会少得多。现在是解决此问题的适当时机,因为诸如 SOA、虚拟化合并和法律法规等力量正在驱动体系结构变更。最近发布的 WebSphere MQ V7.0 包括了自从 MQSeries 的初始版本以来在产品 API 方面的最大变更。此外,新产品正在 WebSphere MQ 上不断层叠,例如 HTTP 桥、WebSphere MQ File Transfer Edition,以及 WebSphere MQ Extended Security Edition 的最近更新。也许当我们集成这些新技术时,我们可以不必花太多的精力去关注它们与现有的实践如何相似,而是去关注它们如何不同。我将非常乐于用几个主题为该讨论埋下伏笔。

面向服务

WebSphere MQ 的遗产主要基于点对点连接、驻留在网络本身中的顶级命名空间,以及主机和队列管理器资产的业务部门所有权关系。SOA 破坏了所有这些假设。SOA 连接模型是任意对任意 (any-to-any) 的。这驱使 WebSphere MQ 偏离点对点并向集群配置发展。现有最佳实践中的一种常见风格是使用集群作为顶级命名空间,并配置多个单独的集群以提供命名空间隔离和路由。但是在 SOA 上下文中,顶级命名空间是在消息网络层之上的注册中心。MQ 拓扑对注册中心命名空间的模仿越接近,垂直通过各层时的名称解析就越透明和无冲突。因此,SOA 驱使 WebSphere MQ 向模仿服务注册中心的单个集群命名空间发展。

SOA 还将集群中的队列和主题视为具有独立资格的目的地。队列管理器变得只不过是个容器,为目的地提供生命保障。因此,虽然对象名称正在向上迁移到逻辑层,但是队列管理器、通道、进程和其他系统名称正在向下转移,更接近物理基础结构层。其结果在于,在业务上下文中命名队列管理器不再有意义;例如,按应用程序名称命名队列管理器。当队列管理器成为共享的基础结构时,在该上下文中命名队列管理器更有意义。当我们从最顶级逻辑名称往下深入到网络中时,按主机名称命名队列管理器将帮助我们模仿网络并定位资产。这与偏离按主机命名队列管理器的趋势相反,按主机命名队列管理器是十年前的普遍实践。

SOA 还改变了队列的关系。在队列名称中嵌入发送和接收限定符的实践在今天非常普遍。在点对点上下文中,此命名约定有助于对网络中的消息流做文档记录。但是在 SOA 上下文中,它违反了服务提供者/服务使用者模型。在 SOA 实现中,唯一众所周知的队列是表示服务端点的队列。此队列按它所表示的服务命名,而不是按提供该服务的应用程序命名。这将队列名称与服务注册中心和逻辑应用程序层绑定在一起。服务使用者只需要一个应答队列,该队列可以是匿名的动态队列或预定义的静态队列。如果该应答队列是静态的,则其最可能按发出服务请求的应用程序命名。服务可以请求其他服务,并且往往会在创建应答队列名称时重用服务 HLQ(高级限定符)。应该避免这样做,因为它可能与服务注册中心的命名空间冲突或导致该命名空间混乱。同时提供和使用服务的任何应用程序都应该对应答队列使用单独的 HLQ。

简而言之,点对点命名约定在 SOA 上下文中的应用往往导致点对点连接模型。尽管集群提供了任意对任意的连接,名称保持了旧的连接样式,但是将名称向上推进到了逻辑层。

主题级别的安全性

在新版本的 WebSphere MQ 中,主题与队列一样是第一级对象。setmqaut 命令用于授予和撤销授权,就像它一如既往地对队列所做的那样,但是具有一些新选项。从表面上看,这似乎是程度上的差异。

但是主题与队列具有根本性的不同。主题名称可以极其长,并由许多任意长度的节点组成。但是,setmqaut 命令仅适用于标准的 48 个字符的对象名称。要创建在主题命名空间中有意义的授权,名称为 48 个字符的主题对象将映射到主题层次结构中的特定点。然后 setmqaut 命令授予或撤销该对象定义上的权限。为了有效解决不存在对象定义的主题节点上的授权请求,将沿着从父节点到子节点的主题树继承权限。

用于主题授权的最佳实践还没有出现。我还不知道它们将是什么样子,但是我知道,如果我们将它们简单视为队列授权模型的扩展,则该“最佳”实践将是错误的。

网络拓扑

在电子工程术语中,总线是电气元件用于通过公共协议以任意对任意的方式交换信号的共享路径。在 WebSphere MQ 术语中,最近似的类比是使用诸如 EDI 或 SWIFT 等公共消息格式组合在一起的集群的任意对任意的连接。但是在 IT 世界中,总线日益被理解为表示某个中央组件,该组件提供诸如中介、路由或转换等公共服务。因此,总线概念正在驱动物理和逻辑网络层的中心和分支拓扑的采用。

这对 WebSphere MQ 非常重要,因为在 MQ 中,远程连接的身份验证在链路上进行。在点对点的网络中,链路级别的身份验证可能是细粒度的。每个节点通常承载不超过一个或两个的相关应用程序,因此链路授权大致等价于驻留在其中的应用程序的授权。单个节点的破坏将使几个相邻节点面临风险。

中心和分支拓扑打破了这种安全模型。必须授权每个分支节点在中心上放置消息。类似地,必须授权每个分支节点从中心接收消息。这里的漏洞在于,分支节点可以不将消息发送到中心的输入队列,而是发送到中心的输出队列。以这种方式使用中心将使任何分支节点都能访问整个网络中的任何目的地。

这里的缓解方法是为每个分支节点创建单独的身份,将该帐户放在入站通道的 MCAUSER 中,并且仅授权它访问特定的服务端点。这种方法的问题在于,它迫使我们将授权策略嵌入物理网络。除了非常难于管理之外,这样也无法很好地适应 SOA 模型,在 SOA 模型中,授权策略是独立于基础传输进行集中管理的。

此话题稍后再谈;该模型的另一个问题在于,中心的损坏将暴露消息网络中的所有业务资产。这不一定意味着可以对任何节点进行管理访问,但是被授权访问中心的所有合法目的地对象都很容易受到攻击。这让人想起分层的安全模型,其中分支节点是基准,对中心加以硬化,类似于网关。

但是最终,这些技术将中心与分支拓扑视为程度上的差异,而实际上是种类上的差异。该拓扑和驱动该拓扑的面向服务的体系结构与过去的点对点构造都是根本不同的。它们正在沿着该堆栈将身份验证从链路往上抬高到消息本身。如果我们不承认这是根本不同的用例,并向其应用旧的安全模型,结果将是容易受到攻击却还以为是高度安全的系统。这比没有安全性还糟糕。

IBM 的 SOA 安全专家 Raj Nagaratnam 博士在最近的采访中解释说,服务基于一种信任模型,其中将授权委托给应用程序外部的策略层。实际上,我们不再能够假设应用程序本身是单个组件。它可能由多个互操作的服务组成。要使授权在这样的组合应用程序中有效和高效地工作,必须将身份与各个事务绑定在一起,而不是与事务流经的渠道绑定在一起。随着 SOA 的成熟,诸如 WebSphere MQ Extended Security Edition 等消息级别的身份验证技术将成为支持新的安全模型的战略组件。





回页首


总结

虽然我提到了一些明确的示例,但我不是在建议立即重新命名所有队列管理器,重新构建网络拓扑,或者重新编写所有客户端应用程序代码。我在这里描述的问题类别特别持久,因为它在大多数情况下都保持休眠状态,因此社区的大部分都不会受到影响。

但是我们重用同样的最佳实践已有如此之久了,基础的模型到目前为止已经偏离,以致差异就代表着重大的潜在风险。这种差距越大,我们所受的影响就越大。如果此过程延续得足够长,遇到其中某个问题的概率将接近 100%。

我在自己的咨询任务中再三地看到这样的情况,其中客户尽管已经坚持不懈地应用了所有的最佳实践,但是仍然遭遇到了重大的中断。上面的示例全都是真实的事件。虽然由于备份集不可用而导致队列管理器恢复失败的情况不常发生,但是我还是看到过几次这样的情况。类似地,我处理过的大多数集群中断都涉及到共享名为 TO.<QMGR> 的通道的重叠集群。就安全性而言,主流的实践完全忽略了身份验证。其结果是经过评估的企业中,有近 95% 的企业公开了匿名管理访问权限。

面对现在发生的所有变化,社区有机会弥补该差距,并让我们的最佳实践与当前采用的用例保持一致。这不需要多大的代价,但是需要更多的参与、社区中积极的对话,以及质疑我们的某些长期存在的传统的意愿。如果我们在在线论坛中检查和改进最佳实践,就可以在合并和虚拟化数据中心、迁移到 SOA 以及部署所有新版本和新产品时开始集成这些最佳实践。更重要的是,我们可以接纳某些重视知识管理方面的适应性和灵活性的文化变化,就像我们在所设计的系统中重视这些属性一样。敏捷性并不是个表面的特性。它要么深沉,要么根本没有。



参考资料

学习

讨论


关于作者

T.Rob Wyatt 是 IBM Software Services for WebSphere 的一名高级管理顾问,负责在 WebSphere MQ 管理、体系结构和安全方面为客户提供帮助。他之前撰写过数篇介绍 WebSphere MQ 管理方面的文章,已经在 Xephon MQ Update 上发表。最近,他重点研究 WebSphere MQ 安全性,并在 IBM WebSphere 开发者技术期刊中发表文章,而且还出席 IMPACT 和 Transaction and Messaging 大会。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款