用校车系统理解事件驱动架构

27天前

就校车系统来说,要解决的问题是:每年如何让700名学生往返他们的家和学校大楼182次?

本文为翻译发表,转载需要注明来自公众号EAWorld。

作者:Jake Miller
译者:白小白 
原题:Event-Driven Architecture: A Primer
原文:http://t.cn/EAr0X43

全文3573字,阅读约需要8分钟


很小的时候,我就被系统迷住了。尤其是一个系统的优雅性最令我着迷。完美的执行、可预见性,一如校车系统的天才创意。

校车系统是如此让我着迷,以至于童年的我几乎每天会在家里的地板上复刻这个过程。当时的我只是认为这个为8岁孩子设计的严谨的交通系统非常棒,但我很快就了解到,世界上有各种各样的系统,有良好设计的系统,也有的系统没有任何设计,有些设计比另一些设计要更好。但最重要的是,系统存在的目标是为了解决问题。

就校车系统来说,要解决的问题是:每年如何让700名学生往返他们的家和学校大楼182次?

每到放学的时候,就会有三排校车停在校园里,亮着黄灯,引擎轰鸣。放学铃声响起,学生们蜂拥而出,急急忙忙地登上每天下午都在同一地点的巴士汽车。

一旦所有的车都坐满了,车门也都关好的,有一位老师就会给打头的司机打个手势,一条满载了小学生的黄色钢铁队列将沿着大山驶上主干道,这个时候,校长会拦停过往的车辆以便每辆巴士都能迅速离开,把孩子们送回家。

我将把这个比喻应用到本文关于事件驱动架构的其余内容中。因此,请注意,这个比喻的各个组成部分是:

  • 中介:即指挥交通的校长。
  • 渠道:即校车和行动路线。
  • 队列:即停车场和停车标志。
  • 事件:即学生。

一、事件驱动架构

近年来,计算领域的各种趋势已经浮出水面:大数据、容器、无服务器应用程序、微服务和事件驱动架构(EDA)。相比单体应用,事件驱动架构让企业可以更快建立更易于管理的可伸缩解决方案,所以越来越受欢迎。

越来越多的企业正在意识到,随着系统必须处理的数据呈指数级增长,传统的RDBMS无法处理这么大的数据量,信息的处理需要长时间运行的基于批处理的ETL来提取业务洞察力。批处理操作用于数据仓库当然没有什么问题,但是实时洞察力的需求对于实现企业想要的结果至关重要。

N层架构示例

在20世纪中期,N层架构大行其道。企业大多会构建由RDBMS支持的单体应用代码库,所有CRUD都是针对RDBMS执行的。但应用程序越来越复杂,它们的依赖关系图谱实际上是不可能理解的。又或者,拼凑了那么多点对点的集成,从而建立了一个脆弱的解决方案。没有人会责怪软件工程师,毕竟,面向对象编程(Object-Oriented Programming,OOP)鼓励代码重用,而在当时,确实只需要服务X来与服务Y对话即可。这很糟糕。

更好的方法

很多企业正开始从单体架构迁移到微服务架构。业务逻辑及相关服务与事件处理器的分离降低了架构的复杂性。服务可以单独开发和部署,不必知道其他服务的存在。微服务架构需要从系统的角度来促进服务间通信。在我看来,为此进行一些初始投资是值得的。

本质上,事件驱动架构促成了去中心化的平台。服务甚至不必驻留在同一个系统或数据中心,也不必由同一个组织所拥有。如果校车系统需要额外的巴士,例如,由于校外活动在不同的学区举行,校车系统可以要求一个或多个系统提供额外的巴士,以应付额外的负荷。这种灵活性允许系统按需扩展和收缩。

二、拓扑结构

很好,如果你认可为事件驱动架构所进行的投资。那么你已经准备好开始建造你的新平台了。现在,您需要决定架构的整体拓扑结构。有两种流行的方案。

中介拓扑结构

如图1所示,中介拓扑结构包括:

事件。
处理所有事件的事件队列。
一个中介,负责管理处理事件的顺序和渠道。
执行业务逻辑的服务。

这是一个抽象的模型,所以,使用何种技术类型的消息队列,以及如何实现中介(也称为控制器或调度器)都取决于你自己。我们团队用GCP(谷歌云平台)Pub/Sub作为消息队列技术的选型,然后在Kubernetes引擎和Google计算引擎上运行Node.js微服务作为控制器。这样我们有N个服务来处理数据并满足面向对象的“单一责任原则”(面向对象五个基本原则SOLID之一,也是微服务的基本原则之一,即一个模块只做一件事)。


用校车系统的比喻来说,假设一辆巴士需要更换刹车和机油,那么中介将把巴士交付给替换刹车的机械师。一旦机械师完成,她将通知中介,然后由中介将巴士交给负责更换机油的技工。

代理拓扑结构

代理拓扑结构,如图2所示,不是利用集中的中介来编排事件和服务。服务向通道订阅消息(接受任务指令),执行它们的业务逻辑,然后发布新消息(表明任务完成),并由其他服务订阅(新的服务接受新的任务指令)。这种方法的一个优点是,通过消除对中介的需求,降低了复杂性。缺点是对执行命令的顺序没有进行协调和和处理。当然,这种模式也是技术无关的。


应用到同一个校车系统的比喻中,如果一辆巴士必须更换刹车,然后更换机油,在代理拓扑结构中,巴士就会放到停车场里,这时,负责换刹车的机械师会收到消息,从而把车辆拉到自己的车间更换刹车,一旦工作完成,他就会把它还放在停车场里,接下来,换油的技师会收到换油卡的消息,并把车停拉到自己的车间里换机油。这个比喻可能有点牵强,但大意如此。

三、性能

对于EDA来说,吞吐量和延迟是两个重要的性能指标。延迟越大,吞吐量就越低。有两个选项可以持续提高系统的性能:通过优化代码或配置来减少延迟,或者通过添加额外的资源来提高吞吐量。

在度量性能时,我建议您的团队为平台中的每个服务定义服务水平目标(Service Level Objects,SLO)和服务水平指示器(Service Level Indicator,SLI)。我们采用了这种方法,它不仅允许我们监视和评估我们在生产环境中的成功之处,而且它为我们在发布新特性之前分析基准和性能测试结果提供了一个指南。

我强烈推荐谷歌出版《网站可靠性工程》(Site Reliability Engineering)这本书,如果你还没有读过的话。

我从构建可伸缩平台中学到的最重要的一件事,那就是每毫秒都很重要。1ms的延迟在低数据量的情况下也许无关紧要,但在处理百万条消息时,每条消息增加1ms的延迟,处理时间就增加了15分钟,如果是10亿条消息的话,处理时间就会增加277个小时。

每毫秒都很重要。在10亿条消息中增加1毫秒的处理时间将使处理时间增加277个小时。

以下是根据我的经验提出的一些建议:

  • 在负载上包含哪些数据,要多动脑筋。
  • 为负载上包含的数据量添加约束,以控制性能和费用。
  • 永远不要使用事务性数据库作为队列,尤其是在处理可能的大数据量时。像SQL这样的数据库必须将每个事务写入事务日志。等待写入事务日志的时间延迟会影响性能。此外,从同一个表中读取和写入将100%导致锁表和IO等待,从而大大增加延迟。
  • 事件驱动系统中有两个重要日期:实际事件日期和处理日期。实际事件日期是用户或系统操作发生的时间。处理日期通常是系统摄取事件的时间。区别这一点很重要,因为如果要在特定的时间窗口中执行任何类型的逻辑,从架构层面应该管理消息的延迟。

解释下最后一个要点,想象一下学校校长被要求清点当天到达学校的所有学生。她需要花20分钟等待所有巴士到达,最后有620名学生抵达学校。至此她就不再数数了。用事件驱动的语言来说,就是时间窗户随之关闭了。但假设因为一个红绿灯坏了,有一辆巴士晚了十分钟。校长将不得不回去,并将额外的80名学生添加到她原来的统计数字中。在您的系统中也必须进行类似的协调。

四、锤子综合征

“当你拿着一个锤子,所有问题看起来都像钉子。”

本质上,事件驱动架构并不是适用所有应用程序的正确模式。恰恰相反,这种模式本身就带来了复杂性。

不要成为锤子综合症的受害者。

如果你本来只需要一把螺丝刀时,EDAS很可能是解决你问题的锤子。在决定这是否是正确的解决方案时,要考虑开发和维护的成本。

在考虑解决方案所需的复杂性以及是否值得进行投资时,请确定已经了解如何处理以下问题:

1、服务抽象的正确级别是什么?

2、您的事件消息是schema还是schema-less的?

译注:
在SQL环境下,schema就是数据库对象的集合,所谓的数据库对象也就是常说的表,索引,视图,存储过程等。
简单来说,在schemaless数据的基本单位被命名为单元(cell)。它是不可变的,一旦写入,便无法被覆盖。(在特殊情况下,我们可以删除旧记录);单元可以被行键(row key)、列名(column name)和引用键(ref key)来引用;单元内容通过编写引用键更高的新版来执行更新,但行键和列名保持不变。Schemaless不对其中存储的数据执行任何操作,故而命名Schemaless。

3、您的系统如何处理由坏的或有冲突的数据以及服务或队列的降级所造成的故障?

4、如何处理邻域噪声问题?

译注:
云是一个多租户环境,这意味着一个单一的体系结构承载了多个客户的应用程序和数据。当应用程序或虚拟机使用大多数可用资源并给共享基础设施上的其他人造成网络性能问题时,就会产生邻域噪声问题。

5、您将如何调试和理解系统中的事件流?

6、如何处理非幂等事件?

译注:
一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。

7、您的系统将如何处理循环预防和检测?

8、您的系统将如何处理分布式事务的回滚?

五、总结

总而言之,EDAS是:

  • 高度可伸缩和去中心化的。
  • 可以在摄取事件的同时处理事件,并执行聚合等功能。
  • 消除点对点集成。

在下列情况下考虑使用EDA:

  • 需要低延迟和大数据量处理,
  • 您需要在时间窗口内实时地聚合或处理数据,
  • 多个服务需要处理同一个事件,
  • 您需要水平扩展分布式系统,并且
  • 您希望实现一个微服务架构。

关于作者:Jake Miller是High Alpha投资的一家初创公司的首席技术官,也是Salesforce Marketing Cloud的前工程总监。




关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享,长按二维码关注

COMMENTS

需要 后方可回复
如果没有账号可以 一个帐号。