企业集成模式-第一章

一、运用模式解决集成问题

1.1 集成的需要

企业一般都由成百上千个应用组成,这些应用要么定制,要么由第三方获得,要么是遗留系统的一部分,也可能是上述应用的组合,它们运行在不同操作系统平台的多个层面上。

也许我们会问:是什么原因造成了这种混乱局面?企业的体系架构如此混乱不堪?不错,凡事都事出有因。

  • 首先,创建商业应用很不容易。
  • 其次,把业务功能分散到多个应用中,这为企业提供了很大的灵活性,可以选择“最好”的财会开发包、“最好”的客户关系管理系统以及“最好”的订单处理系统来满足自己的需要。IT 组织通常对那种“一站式”的企业应用并不感兴趣,况且企业的需求名目繁多,要想提供这样一个“无所不能”的应用也不太可能。
  • 开发商开始学着迎合这种需要, 着力提供围绕一个特定核心功能的针对性应用。 但是,客户不断提出要对已有的软件包添加新的功能,这就造成了一些集成商业应用的功能泛滥。要在系统之间划定清晰地功能界限是很困难的。
  • 用户(如客户、商业合作伙伴和内部用户)在使用商业应用时,一般并不考虑系统的边界。他们只是执行业务功能,而不管这种业务功能是由多少个内部系统实现的。【比如下订单,涉及验证客户ID、检查客户的信用等级、检查库存、履行订单、获得货运报价、核算营业税、交付账单等。这个过程通常会跨越五到六个不同的系统。但从客户的角度看,这只是一个单独的商业交易。】

为了支持常见的商业过程和多个应用间的数据共享,必须把这些应用集成起来。应用集成必须在多个企业应用之间提供高效、可靠和安全的数据交换 。

1.2 集成面临的挑战

  • 企业集成要求公司策略大幅调整。成功的企业集成不但要在多个计算机系统之间建立通信,还要在业务单位和 IT 部门之间建立通信一一在一个集成的企业应用中,特定的应用不再由小组控制,因为每个应用已经成为整个集成应用和服务流的一部分。
  • 由于集成的履盖面很广,通常会对商业应用产生深远影响。一旦把最重要的业务功能加入到一 个集成方案中, 这个解决方案能否正确地履行功能对商业应用至关重者表现不正常,有可能使企业丢失订单、支付有误,引起客户的不满,因而损失几百万美元。
  • 开发集成解决方案最大的限制在于,集成开发人员对所集成的各个应用只有有限的控制。在大多数情况下,这些应用都是“遗留”系统或者是封装好的应用,不会因为要连接到集成方案而作出修改。这就迫使集成开发人员不得不修补应用存在的体胸。 增加新的特性, 或者弥补它们之间存在的差异。如果能在应用端点内部分解决方案会更容易一些, 但是出于政治或技术上的原因,这通常是做不到的
  • 尽管对集成解决方案存在着广泛的需求,但是这个领域内的标准还很少。XML、XSL、Web服务的出现是集成解决方案向标准化迈进的重要标志。但是,对web服务的的大肆宣传也给市场带来了新的格局,这又造成关于标准的新的 "扩展" 和 "实现" 到处泛滥
  • 已有的XML Web 服务标准只是解决了一部分集成问题。这就如同将所有文档都采用一种通用字母表(如罗马字母)来书写。即使字母表是相同的,但仍然可以用来表示不同的语言和方言,所以并非所有读者都能读懂。要在系统之间克服语义方面的差异,这是一项非常困难而耗时的任务,因为它涉及到重大的商业和技术决策。
  • 开发一个EAI解决方案本身就是一项艰难的任务,运行和维护这样的解决方案可能会更加困难。在此会混合大量不同的技术,再加上EAI解决方案的分布特性,因此,要完成复杂任务的部署、监控和故障排除需要各种各样的技能。在大多数情况下,这些技能是由不同的人掌握的,甚至并非IT行业内部的人。

1.3 集成模式有何帮助

如何实现企业集成,对此没有简单的答案。在我们看来,如果有人说集成很容易,这些人要么是难得的天才(至少比我们这些人更聪明),要么就是少有的白痴(这还是乐观的说法),也有可能他们想让你相信集成很简单,以便向你兜售他们的产品而从中获利。

尽管集成是一项覆盖面广、难度很大的工作,仍然有些人确实比其他人做得好。为什么这些人掌握的知识比别人多?显然所谓“21 天集成速成”是不可能的(本书肯定做不到!),因此这些人也不可能知道所有集成问题的答案。但是,他们曾经解决过大量集成问题,能把新问题与已经解决过的老问题进行比较。他们了解问题的“模式”及其相应的解决方案。他们经过长时间的摸索,通过尝试与失败,或者从其他有经验的集成架构师那里取经,才学到了这些模式。

模式并不是可以复制粘贴的示例代码,也不是塑膜包装的组件,而是一些宝贵的建议,描述了针对一些频繁出现的问题有哪些解决方案。如果使用得当,集成模式有助于填补集成的高层目标与具体系统实现之间的鸿沟。

1.4 集成世界

我们有意给集成下一个很宽泛的定义。对我们来说,集成(integration)就是连接计算机系统、公司或人。

在许多集成项目中,我们反复地遇到以下六种类型的集成:

  • 信息门户
  • 数据复制
  • 共享的业务功能
  • 面向服务的体系结构
  • 分布式的业务过程
  • 企业到企业(B2B)的集成

上述清单并没有全面地列出各种类型的集成,但是这确实可以说明集成架构师建立的解决方案。许多集成项目都结合了多种类型的集成。例如,为了把应用组合成一个单个的、分布式的业务过程,往往需要引用数据复制。

许多商业用户必须访问多个系统才能得到某个问题的答案或者完成一项商业活动。

许多商业系统需要访问相同的数据。当客户要求变更其地址时,所有这些系统都需要各自修改客户地址的副本。

许多商业应用不但保存有冗余的数据,类似地,它们可能还实现了冗余的功能。很多系统都要检查社会保险号是否合法、地址是否与相应的邮编匹配、指定的某个商品是否有库存。由此可见,把这些功能提供为共享的业务功能很有意义,这样只需实现一次,这些功能就能为其他系统服务。

1.5 松耦合

松耦合有一个基本的核心,就是在协作双方(组件、应用、服务、程序、用户) 交换信息时要减少对对方做出的假设。双方对对方及公共协议做出的假设越多,通信的效率就越高,但是这种解决方案往往无法忍受服务的中断或变化,因为通信双方被紧密耦合在了一起。

本地方法调用就是紧耦合的一个很好的例子。在应用中调用一个本地方法时,需要对调用和被调用的例程做许多假设。它们都必须运行在同一个进程(如虚拟机)中,并采用相同的语言编写(或者至少使用相同的中间语言或字节码)。调用方法必须准确提供所需的参数,参数个数和类型都必须符合约定。调用是即时的,也就是说,在调用方法做出调用后,被调用的方法要立即开始执行(这意味着,调用是同步的)。方法调用结束后,会自动恢复处理,继续执行调用方法中的下一条语句(即方法调用后面的语句)。方法之间的通信是直接而即时的,所以不管是调用方法还是被调用的方法,都不必考虑第三方窃听这样的安全问题。基于所有这些假设,编写良构的应用会非常容易,可以把功能划分到单个的方法中,再由其他方法调用。这样就会得到许多小方法,可以提高灵活性和重用性。

许多集成方法的目标是把远程数据交换打包,从而采用本地方法调用同样的语义,以简化远程通信。基于这种策略,远程过程调用 (RPC)或远程方法调用 (Remote MethodInvocation,RMI)得以出现。这种方法的好处体现在两个方面。

  • 第一,应用开发人员对同步方法调用的形式非常熟悉,所以,为什么不充分利用已知的知识呢?第二,对本地方法调用和远程方法调用均采用相同的语法,这样可以延迟到部署时再决定哪些组件要在本地运行而哪些应该远程运行,从而减少应用开发人员的负担。
  • 第二,对本地方法调用和远程方法调用均采用相同的语法,这样可以延迟到部署时再决定哪些组件要在本地运行而哪些应该远程运行,从而减少应用开发人员的负担。

所有这些方法都要面对一个难题,由于存在远程通信,所有本地方法调用所依据的许多假设不再成立。因此,把远程通信抽象成一个简单的方法调用,会造成混乱和误解。Waldo及其同事在1994年曾指出,"与在同一个地址空间中交互的对象相比,在分布式系统中交互的对象在处理上存在本质的区别"

例如,如果我们调用远程服务完成某个功能,是不是真的想对这个服务采用的编程语言加以限制呢?非得采用我们使用的语言吗?一个跨网络的调用往往比本地调用慢好几个数量级。调用方法是否确实需要等到被调方法完成后才能执行呢?如果网络中断,被调方法暂时不可达怎么办?到底应该等待多长时间?怎样才能保证是与正确的一方通信,而不是冒充的第三方?如何防止窃听?如果被调方法的方法签名(即所需的参数列表)改变了怎么办?如果远程方法由第三方或商业伙伴维护,我们就无法控制这种改变。那么是让方法调用失败,还是尝试寻找最有可能的参数间映射继续执行调用呢?显然,远程集成带来了本地方法调用永远不会遇到的很多问题。

总之,尝试把远程通信描述成一种本地方法调用是自找麻烦。这种松耦合的体系结构很容易导致失败,也很难维护和扩展。

1.6 EAI简介

image
利用公共数据格式、通过排队通道异步通信和转换器之类的机制,有助于把紧耦合的解决方案转变成松耦合的解决方案。发送者不再依赖于接收者的内部数据格式,也不再依赖接收者的位置,甚至不必关心其他计算机是否已经准备好接收请求。通过消除这些系统间的依赖,可以使整个解决方案更能适应变化,这正是松耦合的主要优点。松耦合方式的主要缺陷是它会增加复杂性。这已经不是一个仅有 10 行代码的解决方案了!因此,我们要使用一个面向消息的中间件基础设施来提供这些服务。

松耦合就是万能的吗?与企业体系结构中的其他方面一样,对此并没有一个最佳的答案。松耦合提供了很多重要的优点,如灵活性和可扩展性,但是它也带来了更复杂的编程模型,使得设计、构建和调试解决方案变得更加困难。

1.7 一个松耦合的集成解决方案

要通过集成解决方案连接两个系统,为此需要解决许多问题。这些功能构成了所谓的中间件(middleware)——也就是应用之间的粘合剂。

通常,必须把一些数据从一个应用传递给下一个应用。这些数据可能是需要复制的地址记录,也可能是对远程服务的一个调用,或者是用于门户显示的一段HTML。无论是哪种类型的数据,都必须能被通信的双方理解,并能通过网络传送。为了实现这一基本功能,需要两个元素:通道和消息。通信通道能把信息从一个应用传送给另一个应用。
image
转换:把一个应用的数据格式转换成另一个应用的数据格式。

路由:中间件负责把消息发送到正确的位置。

消息端点:大多数封装好的应用和遗留系统都没有打算要参与集成,而且许多定制应用也没有考虑过集成问题。为此,我们需要采用消息断点(message endpoint)把这些系统显式地连接到集成解决方案中。端点可能是一段特殊的代码,也可能是一个由集成软件开发商提供的通道适配器(channle adapter)

1.8 示例

WGRUS是一家在线零售商,从制造商那里购买零部件及配件,然后销售给客户。
image
在这个例子中,假设解决方案需要支持以下需求、

  • 接受订单:客户可以通过网络、电话或传真下订单
  • 处理订单:处理订单涉及多步操作,包括检查库存、发货、为客户开具发货单
  • 检查状态:客户可以检查订单状态
  • 修改地址:客户可以通过web前端修改他们的账单和货运地址
  • 更新目录:供应商要定期地更新商品目录。WRGUS必须根据新的商品目录来更新商品的定价和存货情况
  • 发布公告:客户可以有选择地订购WRGUS发布的公告
  • 测试与监控:操作人员应当能够监控所有组件以及组件之间的消息流

下面将分别处理上述各个需求,并使用本书介绍的模式语言来描述各种替代解决方案和折衷考虑。首先从简单的消息流体系结构开始,然后逐步解决更复杂的需求,在此过程中,将会引入更多复杂的概念,如过程管理器(Process Manager)。

1)内部系统

与大多数集成应用环境样,WGRUS并不是所谓的greenfield”实现,而是基于一个已有的IT基础设施实现的集成,其中包括大量封装好的应用和定制应用。由于必须与已有的应用打交道,这往往使集成工作很负有挑战性。在这个例子中,WGRUS 运行着以下系统(如下图所示)。
image
左侧是与客户交互的4个不同的通道。

右侧财会系统还包括账单管理功能,货运系统能够计算并与货运公司协调。出于历史原因,WGRUS有两个库存和目录系统。WGRUS过去只销售零部件,但是现在还需要销售配件的零售商。

2)接受订单

首先要实现的功能是接受订单。接受订单是一项愉快的事,因为订单能带来收入。但是,下订单目前还是一个烦人的手工操作,因此每个订单带来的开销是很高的。

实现流水线订单处理的第一步是统一接受订单。客户可以通过三种通道下订单: Web站点、呼叫中心或传真。遗憾的是,上述每个系统都采用了不同的实现技术,并且把接受到的订单保存为不同的数据格式。呼叫中心系统是一个封装好的应用,而 Web 站点是一个定制J2EE应用。对内传真系统需要把数据项手工录入到一个小型的 Microsoft Access 应用中。我们必须平等对待所有订单,而不考虑它们的来源。例如,客户可以通过呼叫中心下订单,然后通过 Web 站点检查订单的状态。

由于下订单是一个异步的过程,连接了多个系统,所以我们决定实现一个面向消息的中间件解决方案来完成订单输入过程的流水线处理。封装好的呼叫中心应用在开发时没有考虑集成问题,因此需要使用通道适配器把它连接到消息系统。通道适配器是一种能与应用关联的组件,只要应用内部有事件发生,它就能将消息发布到一个消息通道。对于某些通道适配器,应用甚至不会察觉到它们的存在。

对内传真应用中使用了相同的方法,将通道适配器连接到应用数据库。由于Web应用是定制构建的,所以我们在 Web 应用内部实现了消息端点代码,并使用消息传递网关Messaging Gateway)把应用代码与特定于消息传递的代码相隔离。

image
由于每个系统对接收到的订单使用了不同的数据格式,因此要使用三个消息转换器将不同的数据格式转换为一种公共的新订单消息,这种消息要遵循一个规范化数据模型(Canonical Data Model)。规范化数据模型定义了独立于特定应用的消息格式,因此所有应用都能采用这种公共的格式相互通信。如果一个应用的内部格式有变化,只是这个应用与公共消息通道之间的消息转换器需要修改,所有其他应用和消息转换器都不会受到影响。

3)处理订单

既然有了一致的订单消息,并且与消息的来源独立,下一步就是要处理订单。为了履行一个订单,必须执行以下操作:

  • 检查客户的信用等级。如果客户已经有大量未付账单,我们则要拒绝这个新订单
  • 检查库存。如果商品缺货,就不能履行订单
  • 如果客户的信用良好,并且商品有存货,就要把商品和账单发送给客户
    image
    为了把逻辑活动图转换为一个集成设计方案,可以使用发布-订购通道 (Publish-Subscribe Channel)实现分叉动作,使用聚合器(Aggregator)实现合并动作。发布-订购通道把消息发送给所有活动的消费者;聚合器接收多个输入的消息,并把它们合并成一个发出的消息(如下图所示)
    image
    如果库存检查和信用检查都已通过,那么基于内容的路由器就会把消息发送给 VALIDATED_ORDER 通道。

在建立了整个消息流后,下面具体来看看库存系统的功能是如何实现的。在需求部分已知WGRUS有两个库存系统一个是用于零部件库存的管理,另一个用于配件库存的管理。因此,必须把库存查询请求发送给正确的系统。为了对其他系统隐藏库存系统的特性,我们插入了另一个基于内容的路由器,它根据所订购商品的类型把消息发送给正确的库存系统(如下图所示)。例如,只要收到的消息中商品编号以 W 打头,就把该消息发送给零部件库存系统处理,凡是商品编号以G打头的消息,则统统发送给配件库存系统处理。

W-零部件(INVW_CHECK_INV)

G-配件(INVG_CHECK_INV)

image
到目前为止,都只是假设每个订单只包含一件商品。对客户来说,这样做很不方便,因为他们必须为每件商品下一个新的订单。而且,对同一个客户的多个订单,我们要分别发货,这就增加了不必要的货运成本。但是,如果允许接受具有多项商品的订单,那么应该由哪个库存系统来检查订单的库存情况呢?可以使用一个发布-订购通道把订单发送给每个库存系统,让它们挑出能够处理的商品。但是对非法订单应该怎么处理呢?怎样才能发现两个库存系统都不能处理的订购商品?我们想保持基于内容的路由器所提供的集中控个分别路由各个订购商品的新功能制功能,但是还需要一个分别路由各个订购商品的新功能。

因此,需要插入一个分解器(splitter),这个组件能把一个消息划分为多个单个的消息。在此例中,分解器把一个订单消息划分为多个订购商品(order item)消息。每个订购商品消息可以被前面的基于内容的路由器路由到正确的库存系统,如下图所示。
image
很自然,当所有商品的库存情况都已查明后,就要把这些消息重新合并成一个消息。

当设计一个聚合器时,必须做出三个关键决定:

  • 哪些消息可以合并(相关性)?
  • 如何确定所有消息都已接收(完备性条件)?
  • 如何把单个的消息合并成一个结果消息(聚合算法)?

下面让我们逐个地解决这些问题。首先,不能根据客户 ID 来合并订购商品(建立订购商品的相关性),因为客户可能会短时间内连续下多个订单。因此,每个订单必须有唯一的订单ID。在接受订单的解决方案中插入一个内容扩充器(Content Enricher)就能实现这个功能(如下图所示)。内容扩充器组件可以把缺少的数据项添加到输入的消息中。在这个例子中,内容扩充器把一个唯一的订单ID添加到了消息中。
image
既然已经有一个订单 ID来建立订购商品消息的相关性,下面需要为订购商品聚合器定义完备性条件和聚合算法。由于要把所有消息(包括非法的订购商品)路由到聚合器,聚合器可以简单地使用订单中商品的个数(订单消息中的一个字段) 来统计是否所有订购商品都已到达。聚合算法同样很简单。聚合器把所有的订购商品消息重新连接成一个订单消息,并把它发布给VALIDATED_ORDER 通道。

把分解器、消息路由器和聚合器结合起来是很常见的一种用法。我们把它称为组合消息处理器(Composed Message Processor)。为了使绘图简化,我们在原来的消息流图中插入了一个“组合消息处理器”符号。
image

4)检查状态

除了通过消息通道连接系统需要花费时间外,履行订单也要花费一定的时间。例如,所需的某项商品可能缺货,库存系统可以保留库存检查消息,直到新的订购商品到来。这就是异步消息传递的一项优点:通信设计为按组件进行。当库存系统保留消息时,财会系统仍可检查客户的信用等级。一旦这两个步骤均完成,聚合器就可以将合法的订单消息发布给货运和账单系统。

一个长期运行的业务过程也意味着客户与管理者都需要了解特定订单的状态。例如,如果某项商品缺货,客户可以决定只采购有库存的商品。或者,如果客户没有收到商品,可以告诉他(或她)所订购的商品正在处理中(并提供货运公司的跟踪编号),或者库房内部存在耽搁,这是很有用的。

如果采用当前的设计方案,则不利于跟踪订单的状态。相关的消息要流经多个系统。为了在处理环节中确认订单的状态,必须知道与订单相关的“最近”一个消息是什么。发布-订购通道有一项优点,可以添加额外的订购者而不会干扰原来的消息流。利用这一特性,就能够监听新的而且合法的订单,并把它们存储在一个消息存储库(Message Store)中。然后就可以从消息存储数据库中查询订单的状态(如下图所示)。
image
在使用点对点通道的情况下,不能简便地向通道增加订购者,因为点对点通道要保证每个消息只能由一个订购者消费。但是,我们可以插入一个线路分接器 (Wire Tap),这是一个简单的组件,能从一个通道中取出一个消息并把它发布给两个通道。然后就可以使用第二个通道把消息发送给消息存储库,如下图所示。
image
把消息存储到一个中心数据库中还有另一个显著的优点。在原来的设计中,每个消息必须携带额外的数据才能继续沿线处理。有了消息存储库,后续组件通过查询消息存储库就可以获得重要的消息数据,这样中间环节就不用携带这些数据了。我们把这一功能成为声明标签(claim check)——消息可以 '登记' 数据,以便事后查询。这种方法的缺点是访问中心数据库不像采用异步消息通道发送消息那么可靠。

为了提高效率,可将消息存储库转换为一个过程管理器(process manager)

过程管理器是一个系统中的中心组建,用以管理消息流。它主要提供两个功能:

  • 保存消息之间(一个 '过程实例' 中)的数据
  • 跟踪进度,并确定下一步的动作(通过使用一个 '过程模板')

该体系结构把单个的系统(如库存系统) 转变成共享的业务功能,从而能被其他组件访问,这就增加了重用性,并简化了系统维护。这些服务可以通过消息流连接起来(例如,使用组合消息处理器检查每个订购商品的库存状态),或者通过过程管理器协调。需要改变消息流时,使用过程管理器要比以前的方法更简单。

新的体系结构把所有的服务连接到一个公共的服务总线上,从而能被其他任何组件调用。通过增加发现功能,即从中心服务注册库中查找(或“发现”)服务,可以把 WGRUSIT 基础设施转换成一个 SOA。为了加入这个 SOA,每个服务必须提供额外的功能。例如,每个服务必须提供一个接口合约,用来描述这个服务的功能。每个请求/应答服务还需要支持返回地址(ReturnAddress)的概念。基于返回地址,调用者(服务消费者)可以指定一个通道,服务要在这里发送应答消息。这对于服务在不同环境中重用也很重要,每种环境可能需要不同的通道来发送应答消息。
image
过程管理器本身使用一个持久存储库1(采用文件或关系数据库)来保存与每个过程实例相关的数据。为了让 Web接口查询订单的状态,可以向过程管理器或订单数据库发送一个消息。但是,检查状态是一个同步过程一一客户希望能立即获得响应。由于Web 接口是一个定制的应用,所以我们采用直接访问订单数据库的方式查询订单的状态,这种共享数据库是最简单、效率最高的方法,并能保证 Web 接口始终显示最新的状态。该方法的潜在不足是Web接口与数据库属于紧耦合关系,但这还是可以接受的。

要把系统提供为服务存在一个难点,那就是许多遗留系统原来并没有考虑返回地址这样的特性。因此,必须采用智能代理(Smart Proxy)“包装”对留系统的访问。智能代理利用附加功能来改进基本系统服务,使之能加入到SOA中。为了达到这个目标,智能代理会拦截发送到基本服务的所有请求和来自于基本服务的应答消息(如下图所示)。
image
智能代理可以存储来自请求消息中的信息(例如由请求者指定的返回地址),并使用这-信息处理应答消息(例如把消息路由到正确的应答通道)。智能代理对于跟踪外部服务的服务质量(如响应时间)也很有用。

5)修改地址

可以采用两种基本的方法把正确的付账地址和发货地址交给账单管理系统和货运系统:

  • 在每条新订单消息中包含地址数据
  • 在每个系统中保存地址数据,并且当地址改变时进行复制

第一种方法的优点是可以使用已有的集成通道传递额外的信息。其潜在不足是这些额外的数据要流经中间件基础设施,即使地址很少被修改,也要携带在每个订单中进行传递。
image
第二种方法是使用数据复制把修改后的地址传播给所有受影响的系统,这与新订单处理无关。不管在什么时候通过 Web 接口修改了地址信息,都要使用一个发布-订购通道把修改后的地址发送给所有相关的系统。系统在内部存储更新后的地址,并在订单消息到达时使用这个地址。这种方法能减少消息流量(假设客户修改地址的频率比下订单的频率低)。它还能减少系统之间的合。任何用到地址的系统都可以订购 ADDRESS_CHANGE 通道而不会影响其他系统。

由于我们处理的地址有多种类型(发货地址和付账地址),因此必须确保每个系统中保存的地址都是正确的。要避免把付账地址的修改消息发送给货运系统。为此可以使用消息过滤器(Message Filter)对消息进行过滤,只让符合指定标准的消息通过(如下图所示)。
image
应该采用哪种方法实现地址修改呢?在目前这个例子中,消息流量还不是很突出的问因为我们每天只处理几百个订单,所以不管采用哪种方法,从效率上看都是合理的。

我们一般都喜欢明确定义的自包含业务动作,如“修改地址”和“下订单”,因为这对实现业务过程的协调提供了更多的灵活性。现在的问题是,如何确定这些业务动作的粒度及其相关的代价。细粒度的接口需要执行过多的远程调用或发送大量的消息,因而会造成系统运行缓慢。而在一个集成环境下,为了更新一个地址,如果需要发送六到七个消息,这就存在一个很大的开销,不仅如此,我们还要处理消息之间的同步。细粒度的接口还会导致紧耦合。

粗粒度的接口克服了上述问题,但是也要付出代价。发送的消息越少,系统的效率就会越高,而且耦合度也越低。但是,粒度太粗的接口会限制系统的灵活性。如果把发送发货单与修改地址的功能结合到一个外部函数中,那么每次修改地址时都要发送一次账单。因此,最好的做法是根据现实中具体的工作来权衡决定接口的粒度。

6)更新目录

为了下订单,客户首先要查看当前能提供的商品及其价格。WGRUS 的商品目录是由不同的供应商提供的。但是,WGRUS 会向客户提供一项服务,使他们能够在同一网站上浏览所有零部件和配件,并能在同一个订单中订购这两种类型的商品。这项功能是信息门要把多个信息源的信息结合到一个视图中。

由于这两种类型的供应商都是每隔三个月才更新一次商品目录。因此,在 WGRUS 中,如果采用实时消息传递基础设施来广播供应商对商品目录所做的修改,这没有太大的意义相反,我们使用文件传输 (File Transfer)集成把商品目录数据从供应商传送到WGRUS。使用文件还有一个优点,可以使用 FTP 或类似的协议,通过公共网络方便、高效地传输文件与之相比,大多数异步消息传递基础设施在公共Internet上的表现则不佳。

同样地,还可以使用转换器和适配器把数据转换成内部目录格式。但是,这些转换器一次要处理整个商品目录,而不是一个商品。当我们处理大批量相同格式的数据时,采用这种方法效率会更高。
image

7)发布公告

为了改进业务,每隔一定时期需要向客户发布特定的公告。为了避免骚扰客户,系统允许每个客户指定他们感兴趣的消息。另外还要提供适当的功能,向特定的客户群发送特定消息。

发布-订购通道也存在一些缺点。首先,任何订购者都可以监听发布的消息,而不需知道发布者的情况。例如,我们不希望购买量小的客户收到为大客户发布的消息。其次,发布-订购通道只能在局域网中保证工作效率。如果要通过广域网发送数据,就必须为每个接收者发送一个单独的消息副本。如果接收者对这个消息不感兴趣,则会造成不必要的网络流量。

因此,必须寻找一种解决方案,能让订购者决定他们需要的订购首选项,并把独立的消息发送给感兴趣的(授权)客户。为了实现这项功能,我们使用了动态接收表(DynamiRecipient List)。动态接收表结合了两个消息路由模式。接收表 (Recipient List)就是一路由器,它能把一个消息广播给一组接收者。接收表与发布-订购通道的主要区别在于,按收表会为每个接收者提供专门的处理,因此对于谁接收消息能有严格的控制。动态路由器(DynamicRouter)是一个能根据控制消息改变路由算法的路由器。这些控制消息可能是订购者指定的订购首选项。动态接收表就是由这两种模式组合得到的。

image

8)测试和监控

监控消息的正确执行是一个很关键的动作和支持功能。消息存储库可以提供一些重要的业务度量 (metrics)信息,如履行一个订单的平均时间。但是,为了保证集成解决方案能成功运行,我们还需要了解更详细的信息。假设在改进的解决方案中,需要访问一家外部信用中介机构,以便更好地评估客户的信用等级。即使一个客户没有透支记录,但是如果这个客户的信用等级很差,我们同样很可能会拒绝该客户的订单。对于没有任何支付记录的新客户来说,这种做法非常有用。由于这项服务是由外部提供者提供的,所以我们必须为此付费。为了检查提供者的发货单是否正确,可能要跟踪自己的实际使用情况,并把使用情况报告与发货单进行比较。不能只是检查订单个数,因为对于长期客户,业务逻辑可能不需要申请外部信用检查。另外,还要与外部服务提供者达成服务质量 (QOS)协议例如,如果响应时间超过了指定的时间,可能就不必为请求支付费用。

为了确保收费的合理性,我们必须跟踪并记录请求个数以及得到相关响应所需的时间为此必须处理两种特殊的情况。第一,外部服务一次可能处理多个请求,因此要把请求和应答消息一一对应起来。第二,由于我们把外部服务看作是企业内部的共享服务,因此服务消费者要能设置返回地址,这是服务发送应答消息的通道。如果不知道应答消息应该发给哪个通道,就很难把请求与应答消息一一对应起来。

解决的方法还是采用智能代理。把智能代理插入到所有服务消费者与外部服务之间。智能代理拦截每个服务请求,并把服务消费者指定的返回地址替换为固定的应答通道。这样一来,服务就会把所有应答消息发送给智能代理指定的通道。由于代理存储有原始的返回地址,因此它会把应答消息再转发给消费者最初指定的通道。智能代理还能测量服务的耗用时间,即对外部服务发出请求到得到外部请求应答之间所需要的时间,并把这个数据发布到控制总线。控制总线与管理控制台连接,管理控制台负责收集来自不同组件的度量信息。
image
除了要跟踪外部信用服务的使用外,还要确保服务能正常工作。智能代理可以向管理控制台报告在指定的超时间隔内没有接收到应答消息的情况。有时,外部服务返回了应答消息,但是消息中包含的结果不正确,这种情况更难检测。例如,如果外部服务出现了错误,为每个客户返回的信用等级都是零,我们就会拒绝每一个客户的订单。为了防止这种情况的发生,可以采取两项措施。首先,要周期性地在请求消息流中插入一个测试消息(TestMessage)。这个测试消息请求某个已知客户的信息等级。然后使用一个测试数据检验器(testdata verifier) 检查不仅能收到应答,而且应答消息的内容要正确。因为智能代理支持返回地址,测试数据生成器 (test data generator) 可以为测试应答指定一个特殊的应答通道,把测试应答与正常应答区分开来(如下图所示)。image
另一种检测服务异常的有效策略是做统计采样。例如,我们估计因客户信息等级过低而造成的订单被拒概率平均不会超过 10%。如果连续拒绝的订单数超过五个,可能就意味着外部服务或某些业务逻辑出现了异常。管理控制台可以把这五个订单用电子邮件发送给管理员,他会对数据进行快速检查,以确定拒绝这些订单是否合理。

posted @   LHX2018  阅读(150)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 一个费力不讨好的项目,让我损失了近一半的绩效!
历史上的今天:
2021-10-28 mybatis-plus #和$的使用场景
2021-10-28 mybatis-plus使用FIND_IN_SET
2021-10-28 mybatis-plus update的三种方式
2021-10-28 SpringBoot整合XXL-JOB
2021-10-28 SpringBoot使用邮件发送
2021-10-28 SpringBoot使用OkHttp
2021-10-28 Java8 获取当天日期的前一天
点击右上角即可分享
微信分享提示