事件驱动微服务体系架构( 二 )


在流内处理中,组件可以同时对多个事件作出反应,并对多个流和事件应用复杂的操作 。有些流包括持久性,即事件在流上停留的时间可以根据需要延长 。
通过流处理,系统可以重现事件的历史,在事件发生后联机并仍然对其作出反应,甚至执行滑动窗口计算 。例如,它可以从每秒的事件流计算每分钟的平均CPU使用量 。
最流行的流处理框架之一是Apache Kafka 。Kafka是许多项目使用的成熟和稳定的解决方案 。它可以被认为是一种工业强度的流处理解决方案 。Kafka有一个庞大的用户群、一个有用的社区和一个改进的工具集 。
其他的选择
还有其他框架提供流和消息处理的组合,或者提供它们自己独特的解决方案 。例如,Apache的最新产品Pulsar是一个开源的发布/订阅消息系统,它支持流和事件队列,所有这些都具有极高的性能 。Pulsar的特点是丰富的-它提供多租户和地理复制-因此复杂 。据说Kafka的目标是高吞吐量,而脉冲星的目标是低延迟 。
NATS是另一种具有“合成”队列的发布/订阅消息系统 。NATS是为发送小而频繁的信息而设计的 。它提供了高性能和低延迟;然而,NATS认为某种程度的数据丢失是可以接受的,优先考虑性能而不是交付保证 。
其他的设计考虑
一旦你选择了你的事件框架,这里有几个其他的挑战需要考虑:
•Event Sourcing
【事件驱动微服务体系架构】很难实现松耦合服务、不同的数据存储和原子事务的组合 。一个可能有所帮助的模式是事件源 。在事件源中,从来不直接对数据执行更新和删除;相反,实体的状态更改被保存为一系列事件 。
•CQRS
上面的事件来源引入了另一个问题:由于需要从一系列事件构建状态,查询可能会很慢,而且很复杂 。命令查询责任隔离(CQRS)是一种设计解决方案,它为插入操作和读取操作调用单独的模型 。
•事件发现
事件驱动体系结构中最大的挑战之一是对服务和事件进行编目 。在哪里可以找到事件描述和详细信息?事件发生的原因是什么?是哪个团队创造了这个活动?他们在积极地工作吗?
•应对变化
事件模式会改变吗?如何在不破坏其他服务的情况下更改事件模式?随着服务和事件数量的增长,如何回答这些问题变得至关重要 。
成为一个好的事件消费者意味着要为变化的模式编码 。成为一个好的事件生产者意味着要认识到模式更改如何影响其他服务,并创建经过良好设计的事件,这些事件被清楚地记录下来 。
•内部部署vs.托管部署
无论您的事件框架是什么,您还需要在自行部署框架(消息代理的操作并不简单,特别是在高可用性的情况下),还是使用托管服务(如Heroku上的Apache Kafka)之间做出选择 。
反模式
与大多数体系结构一样,事件驱动的体系结构具有自己的一组反模式 。以下是一些需要注意的地方:
设计过多的事件
注意不要对创建事件过于兴奋 。创建太多的事件将在服务之间创建不必要的复杂性,增加开发人员的认知负担,增加部署和测试的难度,并导致事件使用者的拥塞 。不是每个方法都需要是一个事件 。
通用的事件
不要使用通用事件,无论是在名称中还是在目的上 。您希望其他团队了解您的事件为何存在、应该用于什么以及应该在什么时候使用 。事件应该有特定的目的,并相应地命名 。事件与通用名称或通用事件与混乱的旗帜,导致问题 。
复杂的依赖关系图
注意那些相互依赖的服务,并创建复杂的依赖关系图或反馈循环 。每个网络跳都会给原始请求增加额外的延迟,特别是离开数据中心的南北网络流量 。
这取决于保证的订单、交付或副作用
事件是异步的;因此,包含顺序或重复的假设不仅会增加复杂性,而且会抵消基于事件的体系结构的许多关键优点 。如果使用者有副作用,例如在数据库中添加值,则可能无法通过重播事件进行恢复 。
过早优化
大多数产品一开始很小,然后随着时间的推移而增长 。虽然您可能梦想将来需要扩展到大型复杂组织,但是如果您的团队很小,那么事件驱动架构的额外复杂性实际上可能会降低您的速度 。相反,考虑使用简单的体系结构来设计系统,但是要包含必要的关注点分离,以便您可以随着需求的增长将其替换掉 。
期望事件驱动来修复所有问题
在较低的技术级别上,不要期望事件驱动的体系结构能够修复所有的问题 。虽然这种体系结构肯定可以改进许多技术功能障碍的领域,但它不能解决核心问题,比如缺乏自动化测试、缺乏团队沟通或过时的开发-ops实践 。


推荐阅读