0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么Apache Kafka会成为微服务架构事实上的标准和主干

GKwL_infoqchina 来源:InfoQ 2019-12-12 14:10 次阅读

微服务与领域驱动设计(DDD)有着共生关系。所谓领域驱动设计是一种设计方法,在这种方法中我们基于业务领域涉及的内容用软件精心搭建出一套模型,这套模型随着时间的推移而逐渐发展,但并不受运行系统的管道约束。我发现人们喜欢将这种模式与 Apache Kafka 结合起来,这种组合在实践中也运用得越来越多了。在这类项目中,微服务架构通常使用 Kafka 作为事件流平台;而领域驱动设计方法则用来定义各种有界上下文,这些上下文表示应用需要执行的各种业务流程。它们与各种事件结合在一起,创建了一个将各个有界上下文与下游出现的上下文分离的单向依赖图,以创建丰富多样的事件流业务应用。本文将探讨为什么 Apache Kafka 会成为微服务架构事实上的标准和主干——Kafka 不仅取代了其他传统的中间件,而且人们还使用 DDD 和 Kafka 原生 API(如 Kafka Streams、KSQL 和 Kafka Connect)直接构建微服务。 1 微服务

如今人们都想用微服务创建敏捷而灵活的架构,微服务这个术语在很多环境中都很常见。

虽然微服务并不是什么免费的午餐,但它们确实提供了许多好处,解耦就是其中一项优势。解耦是围绕业务功能来组织系统,以形成分散的体系结构的过程。其中智能端点和哑管道(dumb pipe)会确保:

基于微服务构建的应用程序需要尽可能分散开来,同时还保持紧密的协作关系——它们拥有自己的领域逻辑(这些逻辑针对的是各自需要处理的业务问题),且行为更像是经典的 Unix 系统中的过滤器——接收一个请求,对其应用合适的逻辑并生成回应。—— Martin Fowler

https://martinfowler.com/articles/microservices.html

2 Apache Kafka——微服务的事件流平台

应该使用哪些技术来构建微服务架构?这个问题可以分为两部分来回答:

1. 微服务之间怎样相互通信

当我们考虑微服务之间的通信问题时(比如说与同步 HTTP(S) 调用进行通信),大多数人一开始会使用 REST 这个方法。很多用户场景都可以使用这种方法。但是,请求——响应模式所创建的点对点连接会将发送方与接收方的通信来往耦合在一起,这样就很难在不影响其他组件的情况下更改某个组件。

因此许多架构师使用中间件作为微服务通信的主干,以创建解耦、可扩展和高度可用的系统。很多东西都能拿来用作中间件——比如说一些自定义粘合代码或框架、像 RabbitMQ 这样的消息传递系统、像 Talend 这样的 ETL 工具、像 WSO2 这样的 ESB,或者像 Apache Kafka 这样的事件流平台。

2. 如果你要使用中间件,该用哪个?

Apache Kafka 之所以能成为微服务事实上的标准,主要原因是它融合了三个强大的概念:

发布和订阅事件流,类似于消息队列或企业消息传递系统

以容错方式存储事件流

在事件流发生时实时处理

Kafka 将这三大支柱一起内置到了一个分布式事件流平台中,这样用户就可以用可靠、可扩展和容错的方式将各种微服务(例如生产者和消费者)分离开来。

为了更好地理解 Apache Kafka 相比传统中间件(如 MQ、ETL 或 ESB 工具)的优势,请参阅”Apache Kafka vs 企业服务总线——朋友,敌人还是亦敌亦友?”

下面探讨像 Apache Kafka 这样的事件流平台是怎样与领域驱动设计方法建立联系的。

3 用于构建和解耦微服务的领域驱动设计方法(DDD)

领域驱动设计(DDD)最早是由 Eric Evans 在他的一本著作中提出来的方法,用于构建包含复杂业务领域的系统。也就是说你不会将 DDD 应用于基础架构软件或构建路由器、代理或缓存层之类的项目中,而是会应用到解决实际业务问题的软件项目上。这种技术很好用,可以将业务模型与将各种模型连接在一起的管道代码分离开来。将这两部分在软件层面分离开来之后,团队就很容易去设计、建模、构建并改进具体的产品实现。

DDD 方法基于下列原则:

https://techbeacon.com/app-dev-testing/get-your-feet-wet-domain-driven-design-3-guiding-principles

团队需要与领域专家交流,从而使用领域术语搭建领域模型

在领域代码中嵌入领域术语

保护领域知识免受来自其他领域和技术子域的损害

本文讨论的 DDD 核心概念是有界上下文。大型项目通常有许多种领域模型和有界上下文。但开发人员将不同种类有界上下文中的代码组合在一起的过程中,软件系统可能会变得越来越不可靠且难以理解。团队成员之间越来越难沟通,而且人们通常很难搞清楚某个模型不该应用在哪些上下文中。

因此,DDD 要求我们明确定义每个模型所应用的上下文对象。我们在设置边界时需要考虑下列因素:哪个团队拥有该模型、应用程序特定部分的用途、以及诸如代码库和数据库 schema 之类的物理表现等。将各个模型严格约束在自己的边界内后,各个部分就更容易实现和理解,因为我们只需要考虑每个部分所属的一个有界上下文就够了。我们不用再因为其他人泄露的代码而分散精力或感到困惑。正如 Dan North 所说:“专心构建你负责的代码,不用想太多”。

https://www.youtube.com/watch?v=4Y0tOi7QWqM

一个事件流平台可能看起来像这样:

在平台中每个微服务都有自己的有界上下文。从技术角度来看,这可能涉及不同的 API、框架、通信协议和数据存储等。有些部分遵循请求——响应模式,而其他部分则根据需要解决的问题来使用事件。总而言之,每个部分都是一个单独的有界上下文,拥有属于自己的领域模型,并在该模型、业务流程和它与其他部分共享的数据之间建立映射。

那么为什么 Kafka 就是事件流平台的不二之选呢?

4 Apache Kafka 和领域驱动的微服务

Apache Kafka 结合了消息传递和存储能力,使不同的生产者和消费者之间能够完全解耦:

服务端(Kafka broker、ZooKeeper 和 Confluent Schema 注册表)可以与业务应用之间分离开来。

生产者不知道或不关心是谁在消费它们创造的事件。Kafka 为他们处理背压、解决可扩展性和高可用性需求。

生产者的生产工作不受消费者下线影响。

就算新的消费者需要从较早的时间戳开始消费事件,它们也可以随时添加进来。

消费者可以以自己的节奏(批量或实时)处理数据。

消费者可以反复处理数据(例如训练不同的分析模型或从错误和数据损坏中恢复)。

有了这些特性,项目团队就都能拥有自己的领域了;这些领域可以有不同的职责、SLA、版本控制和技术选择。

这种方法不仅适用于业务应用,也适用于公司 IT 团队的运营工作;运营团队可以拥有用于内部自助服务的 Kafka 集群。Kafka 集群通常基于 PaaS 架构部署,例如 Kubernetes 和 Confluent Operator 等。如果使用基于 Confluent Cloud 等托管服务的云部署方案,则通常不需要此类基础架构团队。

5 领域模型、有界上下文和通用语言

如上所述,领域驱动设计(DDD)的关键元素之一是将业务问题分离为许多独立的有界上下文的集合。每个上下文都有一个领域模型,将所需数据完全封装在软件里,还包括需要执行的业务操作以及用于描述这些元素的语言。但是,某个有界上下文中的领域模型该怎样与其他上下文中的模型建立联系呢?我们如何保证一个模型中的更改不会对其他领域模型产生负面影响?

答案就是使用在 DDD 中被称为反腐层(anti-corruption layer)的方法:反腐层将领域模型中使用的数据映射到在各个微服务或有界上下文之间传输的数据上。这个模式与具体的实现无关,这意味着无论你的服务是通过事件还是通过请求——响应协议通信,都可以使用反腐层。在这两种通信方式下通常都会有一种有线格式(可以是用来从 REST 端点返回数据的 schema,或是用来描述事件的 schema,例如存储在 Schema 注册表中的 Avro 消息)。

反腐层有两大职责:

它让领域模型不受其他模型的更改影响

它封装了上下文之间的边界,并描述了它们之间的映射。这种映射既能从技术意义上描述,例如一条消息中的字段 A 映射到模型中的字段 B;也能基于 DDD 的通用语言描述——将事件 schema 中的对手(counterparty)映射到领域模型中的客户(customer)。

每个有界上下文中的模型都会进化发展,而团队在设计改进模型的过程中,要经历的一项关键步骤就是设计将各个模型连接在一起的接口。要走好这一步,首先应该由开发人员和拥有系统的利益相关方共同开发一种通用语言。

6 使用Apache Kafka、Kafka Streams、KSQL和Kafka Connect 将各个领域连接起来

还有一个关键要点我们还没讨论过:Apache Kafka 不仅是一个消息系统或者一个集成层——它是一个事件流平台。这意味着它不仅负责提供用来解耦微服务的中间件,还允许你在客户端代码中执行复杂的数据操作,如拆分、连接、过滤和汇总等。这是 Apache Kafka 和传统中间件之间的另一大区别所在,正如 ThoughtWorks 所解释的那样:

……我们看到一些组织将许多 Kafka 生态系统组件(例如连接器和流处理器)集中在一起,使用 Kafka 重建了 ESB 这种反模式,而不是让这些组件与产品或服务团队共存。ESB 模式有着很严重的问题,人们将越来越多的逻辑、编排和转换推入集中管理的 ESB 中,不得不愈加依赖中心化的团队。我们指出这一现象就是想让人们不要再推进这种有缺陷的模式了。“使用 Kafka 重建 ESB 反模式”

https://www.thoughtworks.com/radar/techniques/recreating-esb-antipatterns-with-kafka

这一点是很重要的。ESB 之所以会包含复杂的逻辑、编排和转换并不是偶然产物,而是因为人们正在构建的业务流程需要它们。ThoughtWorks 的观点并不是说这些过程本身是问题所在,或者没什么必要,而是说问题出在这些过程被推出了本应拥有它们的应用所在的边界,并推入了中心化的基础架构中。这种中心化的基础架构和业务逻辑导致软件愈加脆弱,难以发展——这正是现代化的敏捷软件项目最不想看到的结果。

事件流系统则使用另一种方式处理这个问题。它们基于哑管道(可高度扩展)和智能过滤器构建;要注意这些过滤器比以往的设计更强大、功能更多。嵌入在微服务中的过滤器具有现代流处理引擎的所有功能。没有中心化的逻辑,一切都是完全分散的,这意味着每个有界上下文都有自己的业务逻辑、编排和转换等等。

因此,使用 Kafka 作为中枢系统后,你就可以使用流处理工具提供的更高级抽象来连接在各个有界上下文中创建的模型了。

这样你就可以充分利用 DDD 的所有优势,同时避免 ESB 导致的种种麻烦——诸如紧密耦合、集中管理整个业务流程等。

具体选择实现哪个微服务完全取决于团队的工作需要。你们的微服务可以使用简单的技术接口,如 REST 或 JMS 这样只用来通信的接口。你们也可以构建真正的事件流式微服务,充分利用流处理的能力来操纵事件数据流并将其映射到你们的内部模型上。

前面的例子中提到了许多种微服务。有些情况下会使用 REST(例如在微服务和 UI 之间通信),有些则使用 Kafka Streams 或 KSQL 将不同来源的事件连接在一起。还有的情况下会使用 Kafka Connect 将事件简单地推送到数据库中,以便进一步操作或直接通过事件源模式使用事件。每个微服务都可以选择自己独立的技术实现,与其他微服务和它们选择的技术无关。

如何构建这样的系统人们很容易想到使用 REST、gRPC 或其他一些请求——响应协议构建分散的事件流微服务。但对许多人来说,构建一种基于事件的系统更是观念上的变革。用事件构建系统的方式是多种多样的。它们可以用于“发后即忘”消息传输,也可以用作协作手段。Ben Stopford 的博客文章“在事件的基础上构建服务”进一步解释了这些模式。

你还必须决定该如何管理状态。可以使用 Kafka Connect 等技术在数据库中管理,也可以使用 Kafka Streams API 在托管服务中管理。关于构建有状态事件流的微服务,可以参阅 Ben Stopford 的博客文章“使用 Kafka Streams 和 KSQL 构建微服务生态系统”。

要从宏观层面了解如何将 Connect、Kafka Streams 和微服务组合在一起,可以参阅 Yeva Byzek 的一篇写得很棒的文章。

https://www.confluent.io/blog/stream-processing-part-1-tutorial-developing-streaming-applications

最后,构建微服务生态系统只是问题的第一部分。生态系统构建完成后,你需要对其检测、控制和操作。具体内容可参阅这篇文章。

https://www.confluent.io/blog/journey-to-event-driven-part-4-four-pillars-of-event-streaming-microservices

还有一件事值得一提,就是 Confluent 的 RBAC 功能;它允许在 Confluent 平台上执行基于角色的访问控制。你可以详细配置每个域组可以访问的资源(如 Kafka 主题、Schema 注册表或连接器等)。

只需挑选最适合你的架构即可。例如,你可以让每个 Kafka Connect 群集由负责它的领域团队运营,或者把 Kafka Connect 托管为 Kafka 群集的一部分,并允许团队为其部署连接器。

有这么多工具帮助你使用 DDD 方法构建和运行基于微服务的系统,我希望你能从中获益多多。

7 Apache Kafka+领域驱动设计(DDD)=解耦事件流微服务

虽然有许多方法可以构建微服务架构,但领域驱动设计(DDD)中描述的方法无疑是最强大的,特别是当你构建的系统具有复杂的业务领域(例如医疗保健、金融、保险、 零售)时更是如此。

DDD 中的许多设计原则都能直接用于事件驱动系统,有一些原则本文还没具体涉及到;我强调的是最常见的技术挑战:如何将应用分离到各个有界上下文中,为什么这些上下文的独立性如此重要,为什么需要领域模型,以及这些概念与消息传递、Apache Kafka 和事件的使用有什么关系。

在当今众多工具的帮助下,微服务架构得以使用事件流平台将各个微服务分离开来,并从中获益匪浅。实现可以是请求驱动的,可以是简单的事件驱动系统,也可以是整个事件流业务应用。它们还可以是这些概念的某种混合产物。DDD 提供了一套管理各个部分之间相互作用的基本技术,包括通用语言、有界上下文,schema 和反腐层等。如你所见,事件和消息传递是让这些系统在实践中良好运行的关键因素。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 通信
    +关注

    关注

    18

    文章

    5865

    浏览量

    135270
  • Apache
    +关注

    关注

    0

    文章

    64

    浏览量

    12408
  • 微服务
    +关注

    关注

    0

    文章

    125

    浏览量

    7301

原文标题:为什么 Kafka 会成为微服务架构的事实标准?

文章出处:【微信号:infoqchina,微信公众号:InfoQ】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    NVIDIA NIM微服务带来巨大优势

    服务通过热门 AI 模型为数百万开发者带来高达 5 倍的 token 效率提升,使他们能够立即访问在 NVIDIA DGX Cloud 运行的 NIM 微服务
    的头像 发表于 08-23 15:20 304次阅读

    服务apache如何配置解析php文件?

    在云服务配置Apache以解析PHP文件通常需要以下步骤: 1、安装PHP:首先确保在服务安装了PHP。你可以使用包管理工具(如ap
    的头像 发表于 04-22 17:27 693次阅读

    Prometheus监控业务指标详解

    在 Kubernetes 已经成了事实上的容器编排标准之下,微服务的部署变得非常容易。但随着微服务规模的扩大,服务治理带来的挑战也会越来越大
    的头像 发表于 01-24 10:32 438次阅读
    Prometheus监控业务指标详解

    Apache服务器和Nginx服务

    Apache和Nginx都是常见的开源Web服务器软件,它们用于处理HTTP请求并提供网站和应用程序的服务。下面是对Apache和Nginx的一些基本特点的比较: 一、
    的头像 发表于 01-22 16:48 398次阅读

    游戏公司不使用微服务架构的原因

    微服务基本只有 request/response 的模式。做不了 streaming?微服务通常要求应用是无状态的才能做到水平扩展。streaming 本身就是加入了状态
    的头像 发表于 12-29 11:18 351次阅读

    如何搭建微服务架构的全局图景

    如果一直保持共用数据库的模式,则整个架构会越来越僵化,失去了微服务架构的意义。因此小明和小红一鼓作气,把数据库也拆分了。所有持久化层相互隔离,由各个服务自己负责。另外,为了提高系统的实
    的头像 发表于 12-27 15:16 383次阅读
    如何搭建<b class='flag-5'>微服务</b><b class='flag-5'>架构</b>的全局图景

    如何构建弹性、高可用的微服务

    基于微服务的应用程序可实现战略性数字转型和云迁移计划,对于开发团队来说,这种架构十分重要。那么,如何来构建弹性、高可用的微服务呢?RedisEnterprise给出了一个完美的方案。文况速览
    的头像 发表于 11-26 08:06 376次阅读
    如何构建弹性、高可用的<b class='flag-5'>微服务</b>?

    设计微服务架构的原则

    微服务是一种软件架构策略,有利于改善整体性能和可扩展性。你可能会想,我的团队需不需要采用微服务,设计微服务架构有哪些原则?本文会给你一些灵感
    的头像 发表于 11-26 08:05 437次阅读
    设计<b class='flag-5'>微服务</b><b class='flag-5'>架构</b>的原则

    docker微服务架构实战

    随着云计算和容器化技术的快速发展,微服务架构在软件开发领域中变得越来越流行。微服务架构将一个大型的软件应用拆分成多个小型的、独立部署的服务
    的头像 发表于 11-23 09:26 502次阅读

    springcloud微服务架构

    Spring Cloud是一个开源的微服务架构框架,它提供了一系列工具和组件,用于构建和管理分布式系统中的微服务。它基于Spring框架,旨在通过简化开发过程和降低系统复杂性来帮助开发人员构建弹性
    的头像 发表于 11-23 09:24 903次阅读

    深入探讨微服务和事件驱动架构区别

    微服务不同,事件驱动架构不要求强制的粒度。事件处理器可以有不同的规模,可以是响应特定事件的小型功能,也可以是处理多个事件的大型子系统。在物流系统中,事件驱动架构可以包括用于包裹跟踪更新的小型事件处理器,也可以有更大的子系统用于
    的头像 发表于 10-30 15:06 433次阅读

    Spring Cloud :打造可扩展的微服务网关

    Spring Cloud Gateway是一个基于Spring Framework 5和Project Reactor的反应式编程模型的微服务网关。它提供了丰富的功能,包括动态路由、请求限流、集成安全性等,使其成为构建微服务
    的头像 发表于 10-22 10:03 412次阅读
    Spring Cloud :打造可扩展的<b class='flag-5'>微服务</b>网关

    SpringCloud微服务架构:实现分布式系统的无缝协作

    在深入Spring Cloud之前,让我们首先了解一下什么是微服务架构微服务架构是一种软件架构模式,将一个应用程序拆分为一组小型、独立的
    的头像 发表于 10-12 16:21 594次阅读
    SpringCloud<b class='flag-5'>微服务</b><b class='flag-5'>架构</b>:实现分布式系统的无缝协作

    Kafka架构技术:Kafka架构和客户端API设计

    Kafka 给自己的定位是事件流平台(event stream platform)。因此在消息队列中经常使用的 "消息"一词,在 Kafka 中被称为 "事件"。
    的头像 发表于 10-10 15:41 715次阅读
    <b class='flag-5'>Kafka</b><b class='flag-5'>架构</b>技术:<b class='flag-5'>Kafka</b>的<b class='flag-5'>架构</b>和客户端API设计

    kafka client在 spring如何实现

    消息中间件,比如 Kafka、RabbitMq,只需要简单的引入 jar,就可以通过注解+配置快速集成到项目中。 开始一个 Pulsar Starter 既然已经了解了 Apache Pulsar ,又
    的头像 发表于 09-25 11:21 383次阅读
    <b class='flag-5'>kafka</b> client在 spring如何实现