我们今天来看下事件驱动架构,这个架构主要包括两种拓扑,调度者(Mediator)和代理(Broker)。我们今天主要看一下调度者拓扑。
事件驱动架构模式是一个非常流行的分布式异步架构模式,用来构建高度可扩展性高的应用程序。它也具有高度的适应性,并且可以用来构建小型应用和复杂的大型应用。事件驱动架构是由高度解耦,单一目的的事件处理组件组成,可以异步接收和处理事件。
事件驱动架构模式主要有两个主要的拓扑组成,调度者和代理者。调度者拓扑通常当你需要中心化的调度者通过一个事件协调完成多个步骤的操作时使用,而代理者拓扑则当你想要完成事件链,但是不想要中心化的调度者时使用。由于这两种拓扑的架构特性和实现策略不同,所以对这两种拓扑的深入了解能够使你在具体的场景中能够更好的做出选择。
调度者拓扑
当事件由多个步骤组成,且需要协调执行事件时,就是调度者拓扑的使用场景。例如:股票交易:一个股票交易事件可能需要:
- 验证交易
- 验证股票交易的各种规则
- 将交易分配给代理人,并计算佣金
- 最后再将交易放给代理人
这些步骤需要一定程度的协调以确定哪些步骤是顺序或并行执行。
调度者拓扑有四个主要的架构组件:事件队列,事件调度者,事件通道,事件处理器。整个事件流以客户端发送一个事件到事件队列为起点,将事件传输到事件调度者。事件调度者接收到初始化事件后,通过发送额外的异步事件到事件通道来执行每一步的处理。事件处理器监听事件通道,接收来自事件调度者的事件,并执行事件的具体业务逻辑。下图展示了事件驱动架构中一般的调度者拓扑:
架构可能有上百个事件队列。事件驱动架构模式并指定执行事件队列组件的具体实现;事件对应可能是一个消息队列,WebService,或者两者的混合体。
调度者拓扑有两种类型的事件:初始化事件和处理事件。初始化事件是调度者接收到的事件,处理事件是由调度者生成的,并由事件处理组件接收。
事件调度者组件负责协调初始化事件涉及的所有子步骤。在初始化事件阶段,事件调度者发送具体的处理事件到事件通道,事件处理器接收到事件并处理它。注意:事件调度者并不执行业务逻辑去处理初始化事件,而是将初始化事件分解为多个子步骤/事件。
事件通道是用于事件调度者异步传递多个具体的处理事件到事件处理器。事件通道既可以是消息队列,也可以是消息主题,尽管消息主题被广泛用于调度者拓扑以满足处理事件能够被多个事件处理器处理(基于接收到的事件来执行不同的任务)。
事件处理器组件包含处理事件所需要的应用业务逻辑。事件处理器是自我界定的,独立的,高度解耦的架构组件,在应用程序或系统中执行具体的任务(业务逻辑)。每个事件处理器可以有不同的业务粒度,细粒度(例如:计算订单的销售税),粗粒度(处理保险索赔)。重要:一个事件处理器应该处理单一的业务逻辑,并且不要依赖其他事件处理的来完成它的业务。
事件调度者的实现可以有多种方式。作为架构师,你应该深入理解每个实现方式,以确保你选择的事件调度者能够满足你的业务需求。
最简单和通用的事件调度者是使用开源组件,例如:Spring Integeration,Apache Camel 或者Mule ESB。在这些开源组件中,通过Java代码或者DSL实现了事件流。对于更复杂的调度和编排,你可以使用BPEL(业务流程执行语言)和BPEL引擎(如:开源Apche ODE)来完成。BPEL是类似于标准XML语言,来描述数据和初始化事件的处理步骤。对于大型应用如果需要更复杂的编排(包括人机交互的步骤),你可以使用业务流程管理来实现调度者,例如jBPM。
使用调度者拓扑的关键是理解你的需求并使用正确的调度者实现。使用开源组件来实现非常复杂的业务流程管理编排是一种错误的做法,就像使用BPM解决方案来执行简单的路由逻辑一样。
为了说明调度者拓扑是如何工作的,假设你通过保险公司投保,然后你需要搬家。在这种情况下,初始化事件可以称为搬家事件。调度者处理一个搬家事件的步骤可能包括下图内容:
在初始化事件步骤,事件调度者创建一个处理事件(例如:改变地址,重新计算价格等),发送处理事件到事件通道,并等待事件处理器将事件处理完成(例如:用户处理器,价格处理器等)。这些流程会一直持续直到初始化事件处理完成。每一个箭头代表这个这些步骤可以同步进行(比如:Recalc Quote和UpdateClaims)。
以上内容即事件驱动架构的调度者拓扑,代理拓扑(Broker topology)将会在下一篇来说明。