EDA专题

从DevOps看EDA

  首先我们看看一个案例,一家娱乐公司价值10亿美元项目需要涉及创建一个新的系统以及集成现有系统,主要问题是如何从一个系统状态变化传播到其他系统的生态系统?例如,如果一个客人购买一张票,我们怎么知道这种票是否存在?属于哪个特定的客人?这样我们可以显示他的资料吗?

  我们采用的方式是将这些系统使用事件驱动架构。从高一层来看,这意味着当有趣的事情发生在系统的记录(SOR)中,我们要求系统能够发出事件来标识当前资源已经被改变。在上述的背景下具体售票的例子中:当一个客户购买一张票,我们需要票务系统发出"创造"事件,标识这张新票,然后,通知其他系统创建了新票。这是图1所示。

  使用EDA应用程序有不同的实现,最常见的是利用企业服务总线(ESB)。ESB提供了标准的机制系统用来发布消息给ESB,系统也可以从ESB订阅消息。消息有两种形式:

  • 队列Queue: 队列方便点到点消息传递,这意味着消息生产者可以发送消息到一个消息消费者
  • 主题Topic: 主题使用发布-订阅消息传递,这意味着消息生成方可以将消息发布到零个或多个订阅者

  队列和主题有自己的特定的业务场景。例如,如果你想要一个消息只处理一次,那么就使用一个队列。如果你想发送一个消息到一个特定的目的地,也是使用一个队列。如果你想要一个消息被任意数量的其他系统处理,那么使用一个主题。

  因此,在EDA我们倾向于主题,因为我们想启用新系统能够订阅改变现有系统,而无需改变现有的系统。因为消息生产者不需要知道对其订阅用户,那么我们说这两个系统之间的关系是松散耦合的。换句话说,如果我们添加一个新的系统,比如说一个分析系统,用来跟踪不同的客人的信息,我们就不需要更新票务系统来支持分析系统,分析系统只要订阅由票务系统的主题事件即可。图2显示了这个图形。

  图2显示了当票务系统引发一个事件,客户档案服务以及分析引擎将接收这个事件。新系统可以订阅票务系统的主题和集成它,这些都不需要改变票务系统。

  队列必须保证能交付,这意味着当一个消息发布到队列中,ESB将Hold住消息在队列中直到有人从队列中删除它。另一方面主题是发布消息给所有用户,然后消息即消失。这将导致另一个问题:如果你的主题侦听器死机了呢?你会错过了事件吗?在正常情况下,答案是"是的",你将错过,这就是一个问题!幸运的是,大多数消息代理(ESB的一部分,用来管理消息)有持久订户的概念。如果一个用户注册成为持久订户,那么ESB将Hold住这一信息,直到你的主题侦听器能够接收消息。从操作的角度来看,您需要确保所有关心主题的监听器能够接收所有事件,那么就要以持久durable方式订阅主题。

轻量和重量事件

  事件本身有两种形式:

  • 轻量Light-weight
  • 重量Heavy-weight

  轻量级事件包含改变资源的标识符,然后需要监听器回去调用SOR获得资源的详细信息。如图3所示:

轻量事件

  重量事件包含事件细节,这样回调SOR记录就不需要:

重量事件

  所以你应该使用轻量级还是重量级事件?这,有一个权衡。事件是不能保证同一时间到达-事件是异步的。所以如果票务系统发布以下事件:

  1. 创建票
  2. 更新票记录
  3. 将额外特性加入票

  但是你接受的事件是如下顺序:

  1. 创建票
  2. 将额外特性加入票
  3. 更新票记录

  如果事件担负的机票信息(重量级事件),那,您将创建机票,将特性添加到票,然后覆盖机票已经更新的状态,这样机票最后状态就不包括新添加的特性。结果是,你不会再有票的当前状态。怎么解决这个问题?方法之一是要求事件的时间戳,然后做一些本地处理,以确保你有最新的事件和丢弃任何过早的事件。

  这里存在一个大量的细节工作且容易出错,所以更理想的解决方案是使用一个轻量级的事件和回调。在这个例子中,票务系统是票的"真理之源",所以,当你进行回调,你将会得到保证总会得到票的正确状态。但这是有代价的,即你的票务系统需要能够支持因为回调产生额外的负载。

  在当前这个项目中,我们有两个场景:新系统可以支持轻量级事件产生的额外负载,遗留系统,不支持重量级事件生成的额外的负载。作为DevOps工程师,你是在最好让您的开发人员知道这个建议,因为你了解系统是否可以支持额外的负载。但同时,如果系统可以支持额外的负载和选择轻量级事件,你需要计划基础设施可以支持负载。它并不是小事:在我们的项目中,生成的票务系统每天超过500 k的事件,这是一个大量的额外负载!

工作流程和手工监听

  大多数esb提供工作流的概念,一个工作流当接受到一个事件然后执行可配置的动作。如图4所示:

  结合面向服务的体系结构与ESB工作流将会很强大,工作流可以处理事件,执行转换并调用服务。它使事件处理可配置而不是编码。

  使用ESB工作流的好处是:ESB在其内部进行事件处理,因此它通常执行性能的比自己编写监听器要好。这需要权衡,如果你使用ESB这种方式,你会失去可移植性;因为应用程序业务逻辑被包含在ESB中,所以如果你需要将应用程序移动到另一个环境中,需要将ESB一起移动。如果另一个网站是使用不同的ESB,或者他们不想采用ESB,那么所有的业务逻辑需要重写。

  另一种选择是在代码中手工编写监听器。这些侦听器订阅适当的主题和独立于ESB执行业务逻辑。在这种情况下,您可能不需要一个完整的ESB,只要message broker即可,通常更便宜。但这种可移植性会以牺牲性能为代价。

  作为DevOps工程师,您需要知道开发人员是选择自己手工编写函数,如果他们使用工作流,那么你要为ESB需要添加额外的处理能力。如果他们要手工编写监听器,那么你需要考虑esb和听众之间的额外网络带宽,你需要添加足够的处理能力来实现侦听器。

 

分割

  这取决于你有多少系统集成,您的ESB可能会从分割中受益性能提高。分割基本上意味着你分配资源单独给特定应用程序组件,这样一个系统的负载不影响另一个系统的性能。在我们的大型项目中我们开始没有分割,但负载非常高,我们最终创建了8段不同系统,并且分离不同系统之间的事件。设定应用程序拥有自己的消息资源这样有助于负载隔离。

 

ESB替换

  虽然esb是实现EDA主要机制,但它们不是城里唯一的游戏。正如您可能想到的,:esb有复杂的配置和管理,每天传递数十万甚至数百万消息。还有一种方法,我们使用一个Atom Feed。Atom Syndication Format,下一代的RSS(Really Simple Syndication),是一个标准的格式发布web提要和遵循一个非常HTTP-centric的方法。SOR通过Atom Feed发布事件,消费者订阅接收事件。这种模型非常简单,会不再需要ESB,但就像所有技术一样都有一个权衡:延迟。EDA应用程序会有一个隐式的延迟。也就是在SOR记录改变和其他系统变化之间有延迟,但延迟会很小,当使用拉取Polling机制时,延迟取决于拉取的间隙时间。

还有其他系统支持处理事件,如AkkaApache Storm

 

什么是DevOps

SOA

猜你喜欢