文章
面向服务的架构
| |||
|
作者:Jürgen Kress、Berthold Maier、Hajo Normann、Danilo Schmeidel、Guido Schmutz、Bernd Trops、Clemens Utschig-Utschig、Torsten Winterberg
行业 SOA 文章系列的一部分
2013 年 12 月
摘要:如果我们看看真实的公司及其业务交易,就会发现真实世界根本不是服务驱动的,更多是由事件驱动的。在系统中创建新客户、进行新车预订、车辆被退回或需要维修。所有这些“功能”不仅受到服务的支持,而且也受到精确定义的流程链的支持。
但是,复杂的业务流程很少能够“完全”自动化,因为现实的异常情况和不同业务流程的依赖关系是高度动态的。所以“事件”的概念在我们的架构中非常有用。在本文中,我们将介绍事件驱动型架构并将其与 SOA 中的当前论证链联系起来。
大多数公司现在通过聚合可用数据来收集业务相关信息。通常,数据仓库领域就是将信息浓缩成对先前事件的跟进。这里关注的重点是数据,而不是流程信息,实际上后者的关联性更大。我们不具备准实时处理业务信息的能力,致使公司管理无法更迅速地对事件做出反应。商务智能正在快速发展,力求解决此问题。下面将介绍底层机制,即允许对重要变更做出更快反应的事件。
术语“事件”通常有两层含义。一方面指可感知的发生,另一方面指在计算机系统中的表示。后者又称为“事件对象”。所以该术语本身比较含糊。跟我们有关的是“业务事件”,即公司内的状态变更。
到底是什么意思呢?如图 1 所示,事件是一种“发生的事情”,但如果不在 IT 系统中以某种表示形式通知我们,事件对我们毫无意义。因此,我们认为事件的发生始终伴随着通知。总的来说,我们使用术语“事件发生”。其含义是事件的发生,包括关于此事件已发生的通知。

通过一种规范来描述“事件发生”,该规范用于创建一种 Java 类。例如,该类(即“事件发生”)的具体特征可以是遵循一定顺序的单个事件,由“事件处理器”处理。用于事件引用的唯一标识符、创建操作的时间戳、事件源和事件类型是一些组件,属于以元数据形式对事件进行的最简短描述。
对于事件类型,“事件类”、“事件定义”或“事件图”这几个术语可互换使用。需要注意的是,所有事件都必须是特定事件类型的实例,因为元数据结构就是以这种方式确定的,并通过属性和特性集合表示。所以针对不同类型的事件,“事件处理器”可以有不同反应。
清单 1 以 XML 消息的形式显示了技术事件的描述示例,该消息也可以设置为 POJO 或相似类型的对象:
<event>
- <eventHeader>
<eventSpecificationId>1</eventSpecificationId>
<eventType>Low Inventory Threshold</eventType>
<eventClass>Business</eventClass>
<eventSubClass>Threshold</eventSubClass>
<eventOccurenceId>4019</eventOccurendeId>
<eventTimeStamp>2006-26-06 13:42:00:01</eventTimeStamp>
<eventSource>Inventory Monitor</eventSource>
</eventHeader>
- <eventBody>
<sku>12345678</sku>
<productName>A Good Book</productName>
<currentInventory>12</currentInventory>
<lowThreshold>15</lowThreshold>
<highThreshold>75</highThreshold>
<reorderAmount>42</reorderAmount>
</eventBody>
</event>
清单 1 — 技术事件的描述显示为 XML 消息。
因此在许多连接中,事件与通过 MoM 交换的传统消息非常类似。没有太大的负载,而且必要时还可通过事件处理器扩展内容。我们将讨论以下方法中的一些区别。
“事件驱动型架构”是一个系统架构,在最简单的情况下,通过以下方式执行和管理规则:
如果现实与预期有出入,则更新预期并提供应答。
如果我们重视 SOA 中的松散耦合,EDA 就更进一步了:由于事件是从事件源以中立方式生成并发送至中间件进行处理,所以由事件触发的功能不再可知。在 SOA 中,必须至少已激活特定服务调用。在 EDA 中,我们通常使用术语“解耦”而非“松散耦合”。
事件驱动的应用程序以非常松散耦合(即解耦)的方式使用、处理和和生成所描述的事件。EDA 支持“事件驱动的应用程序”。处理中间件接受事件,评估内容,必要时根据标准目录进行检查,然后通过发布或订阅通知相关使用者。使用者处理事件,事件可以像事件源一样作为服务实现。
事件处理是指对事件执行读取、更改、创建和删除等操作。EDA 的先决条件是现实可能不同于预期。因此,应制定预期、显著差异以及相应的响应行为。图 2 显示了事件处理的典型处理链:

当前复杂架构中的一个严重问题是通常无法充分感知和处理业务事件。单个事件没有意义,导致重要的业务连接被忽略。个别事件发生过于频繁,致使无法充分分析和处理每个事件的起因和影响。筛选相关事件可以减少事件的数量,但无法阐明事件的意义。这意味着在执行“事件检测”之后,我们必须转到“事件关联”阶段。
结果必须相互关联,因为事件关联的意义远大于单个事件。此外,需要进一步处理的事件的数量也因事件关联而减少。这一阶段的挑战是事件的相互关系往往难以确定,并且事件通常分布在整个应用程序环境中。因此,识别大量事件中的模式有着特殊意义。
第三个阶段是对事件的反应。与使用服务调用或状态消息一样,对简单事件做出反应没有任何问题。许多基础工具均可实现,如 SOA 或 BAM 仪表盘。但是,状态信息大多数情况下都在用户的大脑中进行解释,至少目前是这样。无法与复杂的事件模式或来源截然不同的事件组合自动比较。因此,当前反应能力非常依赖于员工、员工的经验和敏锐的注意广度。复杂事件处理引擎可为此提供支持。
因此,复杂事件处理 (CEP) 明显有别于基于队列或数据库的传统处理机制。临时存储是必要的,因为它允许对不同类型的事件进行复杂的关联,甚至支持较大的时间跨度。这也称为“流内处理”,正变得越来越重要,从 SQL 类型(基于流的查询语言)可以看出。
我们通常要区分三种类型的事件处理。
在简单事件处理 (SEP) 中,只有“相关”事件才会被放入事件通道中进行处理。比如“XY 类别的汽车已售罄”或“冬季轮胎库存紧张”。这非常类似于基于消息的系统。处理逻辑评估事件类型和内容,然后相应地做出反应。
在事件流处理 (ESP) 中,除了“相关”事件以外,“通常的”事件(如所有一般指令或 RFID 事件)也会发布到事件通道中。这对事件处理提出了更高的要求,同时也提供了更多评估选项。
最后,复杂事件处理 (CEP) 处理同时发生的不同事件,以确定这些事件对应的操作。事件通道中的事件可以有不同的事件类型,并且可以长期发生。可以根据内容、时间或位置来关联事件。因此,CEP 通常用于检测异常、风险,甚至业务机会,旨在利用相比传统报告解决方案更具现时性的信息的优势,最终在竞争中占据上风。
ESP 与 CSP 之间的区别到底是什么?ESP 是流的处理,其中事件流是按时间顺序排列的事件序列,如股票行情自动收录器。而 CEP 工作在称为“事件云”的“云”上。事件云是来自 IT 系统不同部分的多个事件生成活动的结果。事件云可能包含多个流。因此,流是云的一个特殊实例。
在流内使用时间顺序有自己的优点:处理速度快,因为只有少数几个事件需要保存在缓冲区中。但是,依赖关系在云中非常重要:发生了哪些依赖事件?或者通常更精彩的是:或许没有发生哪些事件?
很明显,事件流处理侧重于高速处理,而 CEP 的重点是从事件云提取信息。在实践中,由于 ESP 和 CEP 之间的差别变得模糊,所以更强大的 CEP 占据了主导地位。
事件服务器对所需的基础架构没有特殊要求。企业服务总线或消息处理基础架构用于传输和路由事件。复杂事件处理引擎用于筛选、聚合和关联事件,通常可作为 JBI 服务引擎与 ESB 相连。最终用户通过 Business Activity Monitoring (BAM) 仪表盘、单独的服务调用或流程调用来集成。
图 3 显示了一个典型的基础架构:

正如简介中所介绍的那样,与其说世界是服务驱动的,还不如说世界是事件驱动的。大多数情况下,SOA 标识符是服务的松散耦合、客户端在提供者与使用者之间发起的 1:1 通信以及同步响应行为。EDA 的标识符是分离的交互、n:m 通信、事件驱动的操作和异步操作。我们认为没有必要确定一端或另一端。SOA 为 EDA 提供了非常坚实的基础,应用程序可以同时采用这两种风格。在以下情况下,组件应使用 SOA 调用服务:
在以下情况下,组件应使用 EDA 发布事件:
从这方面来说,“2 + 2 > 4”,因为这两种架构风格的组合大于各部分之和。SOA 在执行预定义的流程和逻辑时使用“请求-应答”通信模式(可能是异步方式,请求与响应之间的时间间隔比较长)。相比之下,ED 应用程序使用典型的“发布者/订阅者”模式,在某些情况下可处理大量事件,旨在创建更少的新“可操作”事件。SOA 与 EDA 是相辅相成的:结合使用可以创建按需提供的高商业价值应用程序。
经常乘飞机旅行的人都非常熟悉一个令人不快的问题“我的行李在哪里?”在值机柜台,旅客与行李分离。飞行结束时,旅客需要经过一系列流程才能取回行李,包括:
最好的临时结果是飞机按时起飞,乘客和行李都在飞机上。然而,我们很多人都知道,可能会发生许多导致事情变得复杂的事件。行李可能在会在办理登记手续与登机之间丢失。乘客可能因安检处排队导致误机。行李可能包含禁带物品,需要搜查。航班可能取消,乘客可能改飞其他地方。乘客办理登记手续后可能决定改签航班。也可能发生其他复杂情况。
在这种情况下,SOA、EDA 或两者的组合可以提供最佳 IT 支持吗?
在做决定之前,需要考虑的是:所描述的场景并不是单个“登机服务”或流程。而是一系列相互影响的服务/流程。交互非常复杂,取决于多个边界条件,因此这是一个典型的“感知与响应”场景,或者说是在必要时启动 SOA 服务的 EDA 技术。试图将这种场景统一在一个可执行的流程中势必会陷入一片混乱。
| 流程 | 事件 |
|---|---|
| 办票 | 乘客办理登记手续、检查行李 |
| 安检 | 乘客进入/离开安检区 |
| 行李处理 | 在安检站扫描行李、行李装入集装箱 |
| 舱门操作 | 舱门打开、登机、最后登机、关闭 |
| 航班操作 | 登机口、装载集装箱、出发、起飞 |
| 客户服务 | 新航班复查行李 |
表 1:航班的各种事件。

非常简单但有效的事件应用领域是打造涉及分布式数据管理的解决方案。例如,如果无法创建单个数据访问点,那么根据简单事件处理使用事件汇集与出租车有关的一切的业务实体服务是一个可行的解决方案。在数据库中输入数据时,可以创建一个“car_rented-event”,将通过简单的处理逻辑获取。可通过这种方式在其他系统中永久存储必要的信息。
我们已经表明 SOA 和 EDA 不是相互竞争的架构,而是相辅相成的架构。EDA 通常可以很好地描述现实世界,并且通常可以轻松地从流程模型中读取事件。如果特定数据有多个使用者,EDA 比 SOA 更高效,因为需要编程的服务调用并不多。这是因为源系统中唯一生成一个事件已经足够。功能强大且具有特殊 EDA 功能的中间件最近越来越多。应用程序开发人员在事件驱动型系统的设计方面欠缺经验,单个组件的高度分离性为故障排除提出越来越多的挑战,这些都是目前不利的一面。然而,众多制造商都初步表露中这样一种迹象,即随着运行时监视技术的改进,这种复杂性将得以改善。
[REF-1] Berthold Maier、Hajo Normann、Bernd Trops、Clemens Utschig-Utschig、Torsten Winterberg:“Rent your Car – Service-Oriented”,Java Magazine,2008 年 11 月刊