事件驱动的微服务架构的最佳实践
Posted 脚本之家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件驱动的微服务架构的最佳实践相关的知识,希望对你有一定的参考价值。
脚本之家
你与百万开发者在一起
你做到了吗?
作者 | Jason Skowronski
译者 | 小冲2019
出品 | 脚本之家(ID:jb51net)
她正在做她的“最佳实践”。
如果您是企业架构师,您可能已经听说过并使用过微服务架构。虽然您过去可能已将REST用作服务通信层,但越来越多的项目正在转向事件驱动的体系结构。让我们深入探讨这种流行架构的优缺点,它所包含的一些关键设计选择以及常见的反模式。
什么是事件驱动的微服务架构?
在事件驱动的体系结构中,当服务执行其他服务可能感兴趣的某项工作时,该服务会生成事件 - 执行操作的记录。其他服务使用这些事件,以便他们可以执行事件所需的任何自己的任务。与REST不同,创建请求的服务不需要知道使用请求的服务的详细信息。
这是一个简单的例子:当一个订单放在电子商务网站上时,会产生一个“下订单”事件,然后由几个微服务消费:
有序服务,可以将订单记录写入数据库。
客户服务,可以创建客户记录。
付款服务,可以处理付款。
事件可以以各种方式发布。例如,可以将它们发布到保证将事件传递给适当的消费者的队列,或者可以将它们发布到发布事件并允许访问所有感兴趣的各方的“发布/订阅”模型流。在任何一种情况下,生产者都会发布事件,消费者会收到该事件,并做出相应的反应。请注意,在某些情况下,这两个actor也可以称为发布者(生产者)和订阅者(消费者)。
为什么使用事件驱动的体系结构
事件驱动的体系结构提供了多种优于REST的优势,其中包括:
异步 - 基于事件的体系结构是异步的,没有阻塞。这允许资源在他们的工作单元完成后自由移动到下一个任务,而不用担心之前发生的事情或接下来发生的事情。它们还允许事件排队或缓冲,从而防止消费者对生产者施加压力或阻止它们。
松散耦合 - 服务不需要(也不应该)了解或依赖其他服务。使用事件时,服务独立运行,不了解其他服务,包括其实现细节和传输协议。事件模型下的服务可以独立且更容易地更新,测试和部署。
轻松扩展 - 由于服务在事件驱动的体系结构下解耦,并且服务通常只执行一项任务,因此追踪到特定服务的瓶颈,并且扩展该服务(并且只有该服务)变得容易。
恢复支持 - 具有队列的事件驱动架构可以通过“重放”过去的事件来恢复丢失的工作。当消费者需要恢复时,这对于防止数据丢失是有价值的。
当然,事件驱动的体系结构也有缺点。通过分离紧密耦合时可能更简单的问题,它们很容易过度设计; 他们可能需要大量的前期投资; 并且通常会导致基础架构,服务合同或模式,多语言构建系统和依赖关系图的额外复杂性。
也许最重要的缺点和挑战是数据和事务管理。由于它们的异步性质,事件驱动模型必须小心处理服务之间的不一致数据,不兼容的版本,监视重复事件,并且通常不支持ACID事务,而不是支持更难以跟踪或调试的最终一致性。
即使存在这些缺点,事件驱动的体系结构通常也是企业级微服务系统的更好选择。专业可扩展,松散耦合,开发友好的设计 - 超过缺点。
何时使用REST
但是,有时候REST / Web界面可能更适合:
您需要一个异步请求/回复接口。
您需要支持强大的交易。
您的API可供公众使用。
您的项目很小(REST设置和部署起来要简单得多)。
您最重要的设计选择 - 消息传递框架
一旦确定了事件驱动的体系结构,就应该选择事件框架了。生成和使用事件的方式是系统中的关键因素。存在数十种经过验证的框架和选择,选择正确的框架和选择需要时间和研究。
您的基本选择归结为消息处理或流处理。
消息处理
在传统的消息处理中,组件创建消息,然后将其发送到特定(通常是单个)目的地。已经闲置并等待的接收组件接收该消息并相应地动作。通常,当消息到达时,接收组件执行单个过程。然后,该邮件将被删除。
消息处理体系结构的典型示例是消息队列。虽然大多数较新的项目使用流处理(如下所述),但使用消息(或事件)队列的体系结构仍然很受欢迎。消息队列通常使用“存储和转发”系统的代理,其中事件从代理传递到代理,直到它们到达适当的消费者。ActiveMQ和RabbitMQ是消息队列框架的两个流行示例。这两个项目都有多年的经过验证的使用和已建立的社区。
流处理
另一方面,在流处理中,组件在达到某个状态时发出事件。其他感兴趣的组件在事件流上侦听这些事件并做出相应的反应。事件不是针对某个收件人,而是针对所有感兴趣的组件。
在流处理中,组件可以同时对多个事件做出反应,并对多个流和事件应用复杂的操作。一些流包括持久性,其中事件在必要时保留在流上。
通过流处理,系统可以重现事件历史,在事件发生后上线并仍然对其作出反应,甚至执行滑动窗口计算。例如,它可以从每秒事件流计算每分钟的平均CPU使用率。
Apache Kafka是最受欢迎的流处理框架之一 。Kafka是许多项目使用的成熟稳定的解决方案。它可以被认为是一种首选的工业级流处理解决方案。Kafka拥有庞大的用户群,有用的社区和不断发展的工具集。
其他选择
还有其他框架可以提供流和消息处理的组合或它们自己独特的解决方案。例如, Pulsar是Apache的新产品,是一个开源的pub / sub消息系统,支持流和事件队列,所有这些都具有极高的性能。Pulsar功能丰富 - 它提供多租户和地理复制 - 因此很复杂。据说Kafka的目标是高吞吐量,而Pulsar的目标是低延迟。
NATS是具有“合成”排队的备选发布/订阅消息系统。NATS旨在发送小而频繁的消息。它提供高性能和低延迟; 但是,NATS认为某些级别的数据丢失是可以接受的,优先考虑性能而不是交付保证。
其他设计考虑因素
选择事件框架后,还需要考虑以下几个其他挑战:
活动采购
很难实现松散耦合服务,不同数据存储和原子事务的组合。可能有用的一种模式是 Event Sourcing。在事件源中,永远不会直接对数据执行更新和删除操作; 相反,实体的状态更改将保存为一系列事件。
CQRS
上述事件采购引入了另一个问题:由于状态需要从一系列事件构建,因此查询可能既缓慢又复杂。命令查询责任分离(CQRS)是一种设计解决方案,它要求插入操作和读取操作的单独模型。
发现活动信息
事件驱动架构中最大的挑战之一是编目服务和事件。您在哪里可以找到活动描述和详细信息?活动的原因是什么?什么团队创建了这个活动?他们是否积极致力于此?
处理变革
事件架构会改变吗?如何在不破坏其他服务的情况下更改事件架构?随着您的服务和事件数量的增长,您如何回答这些问题变得至关重要。
作为一个好的事件消费者意味着编码改变的模式。作为一个好的事件生产者意味着要认识到你的模式变化如何影响其他服务,并创建明确记录的精心设计的事件。
内部部署与托管部署
无论您的事件框架如何,您还需要自己决定在内部部署框架(消息代理不是很容易操作,尤其是高可用性),或者在Heroku上使用Apache Kafka等托管服务。
反模式
与大多数体系结构一样,事件驱动的体系结构具有自己的一组反模式。以下是一些需要注意的事项:
好太多了
小心你不要对创建事件感到太兴奋。创建太多事件将在服务之间产生不必要的复杂性,增加开发人员的认知负担,使部署和测试更加困难,并导致事件消费者拥塞。并非每种方法都需要成为一种事件。
通用事件
不要在名称或故意使用通用事件。您希望其他团队了解您的事件存在的原因,应该使用的内容以及何时应该使用它。事件应具有特定目的并相应地命名。具有通用名称的事件或具有混淆标志的通用事件会导致问题。
复杂的依赖关系图
注意彼此依赖的服务并创建复杂的依赖关系图或反馈循环。每个网络跃点都会为原始请求增加额外的延迟,尤其是离开数据中心的北/南网络流量。
取决于保证订单,交货或副作用
事件是异步的; 因此,包括对顺序或重复的假设不仅会增加复杂性,还会抵消基于事件的体系结构的许多关键优势。如果您的消费者有副作用,例如在数据库中添加值,那么您可能无法通过重播事件来恢复。
过早优化
大多数产品从小开始,随着时间的推移而增长 虽然您可能梦想未来需要扩展到大型复杂组织,但如果您的团队规模较小,那么事件驱动架构的复杂性可能会让您失望。相反,考虑使用简单的架构设计您的系统,但包括必要的关注点分离,以便您可以随着需求的增长进行交换。
期待事件驱动来解决所有问题
在技术水平较低的情况下,不要指望事件驱动的架构能够解决您的所有问题。虽然这种架构肯定可以改善技术功能障碍的许多方面,但它无法解决核心问题,例如缺乏自动化测试,团队沟通不畅或者过时的开发实践。
学到更多
了解事件驱动架构的优缺点,以及一些最常见的设计决策和挑战是创建最佳设计的重要部分。
如果您想了解更多信息,请查看这个事件驱动的参考架构,它允许您通过单击在Heroku上部署工作项目。该参考架构创建了一个销售虚构咖啡产品的网上商店。
产品点击次数作为事件进行跟踪并存储在Kafka中。然后,它们被报告仪表板使用。
代码是开源的,因此您可以根据需要对其进行修改并运行您自己的实验。
本文翻译作者简介:小冲2019
本文为 脚本之家专栏作者 翻译,转载请注明来源出处。
写的不错?赞赏一下
长按扫码赞赏我
●
●
●
●
●
返回 上一级 搜索“Java 女程序员 大数据 留言送书 运维 算法 Chrome 黑客 Python javascript 人工智能 女朋友 mysql 书籍 等关键词获取相关文章推荐。
以上是关于事件驱动的微服务架构的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章