首页 > 其他分享 >浅析 Dapr 里的云计算设计模式

浅析 Dapr 里的云计算设计模式

时间:2022-10-24 16:35:13浏览次数:115  
标签:服务 gRPC Actor Dapr HTTP 设计模式 浅析 Sidecar

Dapr 实际上是把分布式系统 与微服务架构实践的挑战以及k8s 这三个主题的全方位的设计组合,特别是Kubernetes设计模式 一书作者Bilgin Ibryam 提出的Multi-Runtime Microservices Architecture,中译参见敖小剑的博客: [译] 多运行时微服务架构。

Dapr 实际上是把分布式系统 与微服务架构实践的挑战以及k8s 这三个主题的全方位的设计组合,特别是​​Kubernetes设计模式​​​ 一书作者​​Bilgin Ibryam​​​ 提出的​​Multi-Runtime Microservices Architecture​​​,中译参见敖小剑的博客: ​​[译] 多运行时微服务架构​​。

分布式系统 和微服务架构实践的核心问题就是要解决系统复杂性这个难题,降低复杂性的通常做法就是分而治之,Dapr的最核心的设计就是​​Sidecar Pattern​​​ + ​​Building Block,如下图:​

浅析 Dapr 里的云计算设计模式_设计模式

图片来源:​​https://docs.microsoft.com/zh-cn/dotnet/architecture/dapr-for-net-developers/dapr-at-20000-feet​

  • ​Sidecar Pattern​​: 通过职责分离与容器的隔离特性,降低应用程式的复杂度。
  • ​Building Block​​:  类似于乐高搭积木方法,通过Dapr 提供的核心组件(Component),分离与抽象化系统架构。

Dapr 设计上几乎和​​Bilgin Ibryam​​​ 提出的​​Multi-Runtime Microservices Architecture​​ 不谋而合,它有几个核心的设计点:

  1. Sidecar
  2. Building Block & Component
  3. Service Invocation
  4. Middleware
  5. State

基于上面的这些核心设计,Dapr 有了多运行时微服务架构 的特性,以此延伸出底下的重要功能,或者说设计模式:

  1. Security
  2. Observability: tracing, metrics, logs and health
  3. Pub / Sub / Batch Process
  4. Actors
  5. Secret Management
  6. Config Management 正在开发中……

Sidecar

Sidecar是非常重要的云计算设计模式,下面这张图是 Sidecar 与Microservice 之间搭配后形成多个服务的关系图,这样的结构形成了服务网格的概念, Dapr 通过配置的方式,动态生成Sidecar ,随后伴随着App,一组Dapr Sidecar + App 的组合称为​​Dapr App​

浅析 Dapr 里的云计算设计模式_dapr_02

Dapr App 在K8s 里面的形态就是 Pod = (App_Container + Sidecar_Container)

浅析 Dapr 里的云计算设计模式_dapr_03

同样的概念,如果Dapr App跑在k8s外面,也就是​​自承载模式​​。 在自承载模式下,微服务和 Dapr sidecar 在没有容器业务流程协调程序(如 Kubernetes)的单独本地进程中运行。

浅析 Dapr 里的云计算设计模式_设计模式_04

每个Dapr App 都通过Sidecar 沟通,在通信之前,Dapr App 要知道的是对方在哪?所以服务发现和服务调用是Dapr App 要解决的第一个问题,知道彼此在哪了,然后就是通信模式,Dapr 支持HTTP / gRPC 两种通信模式。 Dapr App 之间的默认的通信模式使用gRPC,也就是如果使用HTTP调用Dapr API,内部服务之间的通信也会转成gRPC。

gRPC 是一种新式的高性能框架,它通过 ​​RPC ​​(远程过程调用) 改进。 gRPC 使用 HTTP/2 作为传输协议,该协议通过 HTTP RESTFul 服务提供显著的性能增强,包括:

  • 对通过同一连接发送多个并行请求的多路复用支持 - HTTP 1.1 将处理限制为一次处理一个请求/响应消息。
  • 双向全双工通信,用于同时发送客户端请求和服务器响应。
  • 内置流式处理,支持对大型数据集进行异步流式处理的请求和响应。

若要了解有关详细信息,请查看适用于 Azure 电子书的​​.NET Cloud-Native中的​​​ ​​gRPC​​概述。

Dapr Sidecar 有了服务调用、服务发现和通信模式之后,定义出来了一个Building Block (构建块)的概念,使用声明的方式,定义多个组件Component 扩展Sidecar的能力,这些能力正是分布式系统需要面对的问题。

构建块 和 组件

构建基块封装分布式基础结构功能。 可以通过 HTTP 或 gRPC API 访问该功能,目前版本有如下构建块。

浅析 Dapr 里的云计算设计模式_设计模式_05

Buiding Block 是每个 Dapr Sidecar 可以扩展的概念,每个 Block 由多个 Components 组成,开发者可以自行设计、扩展 Component,然后贡献给社区,这里集中了社区贡献的组件 ​​https://github.com/dapr/components-contrib​​​。 我们来看一下微软的.NET团队基于Dapr 设计的​​eshopondapr​​,图中每个Dapr标示都是一个Component ,一共标记了六种:

浅析 Dapr 里的云计算设计模式_设计模式_06

基于这样的设计,Dapr 把最核心的Component 提供了基于分布式系统的 ​​最佳实践 (Best Practice)和 设计模式​​​​ (Design Patterns)​

  1. ​Input/Output Bindings​​:

这些核心的设计可以通过代码仓库了解:

浅析 Dapr 里的云计算设计模式_ide_07

仓库 ​​https://github.com/dapr/components-contrib​​ 是Dapr 官方开放的Component ,开发者可以通过 PR 提交来把 扩展的Component 贡献给社区,目前已经有70 多个Components 可以使用,使用的时候要注意版本的阶段性是在Alpha / Beta / GA,一定要做好风险评估。

服务调用和服务发现

这就是我们在微服务里面常说的服务治理,Dapr 作为一个分布式系统,多个Dapr app怎么知道彼此的存在,通过什么方式进行沟通,这就是Dapr的服务治理要解决的问题,Dapr的服务发现机制,按照架构的不同方式(k8s还是自托管)有不同的实现,官方文档(​​https://docs.dapr.io/zh-hans/developing-applications/building-blocks/service-invocation/service-invocation-overview/​​)里的这张图介绍了调用逻辑

浅析 Dapr 里的云计算设计模式_微服务_08

  1. 服务 A 对服务 B 发起HTTP/gRPC的调用。
  2. Dapr 使用​​name resolution component​​ 发现 Service B’s 位置 取决于运行的环境 ​​hosting platform​​.
  3. Dapr 将消息转发至服务 B的 Dapr 边车
    : Dapr 边车之间的所有调用考虑到性能都优先使用 gRPC。 仅服务与 Dapr 边车之间的调用可以是 HTTP 或 gRPC
  4. 服务 B的 Dapr 边车将请求转发至服务 B 上的特定端点 (或方法) 。 服务 B 随后运行其业务逻辑代码。
  5. 服务 B 发送响应给服务 A。 响应将转至服务 B 的边车。
  6. Dapr 将消息转发至服务 A 的 Dapr 边车。
  7. 服务 A 接收响应。

这里面有很多核心的概念:

  • Dapr 命名有Namespace 概念,基本格式为FQDN
  • Dapr 的Service Invocation 支持 gRPC / HTTP 两种方式,默认的 Service to Service 使用gRPC 通信。
  • Service to Service 使用mTLS 做传输层加密
  • 支持 Service 的ACL,可以个别控制每个API 与Method 的操作
  • 支持 Retry 机制
  • 可以使用其他service discovery 实现
  • RR load balancing with mDNS
  • 支持tracing 和 metric

Middleware

和ASP.NET Core 支持通过 middleware 处理 HTTP request / response 完成一些 Cross-Cutting (AoP) 的功能,Dapr 也支持 Middleware 的概念,如下图:

浅析 Dapr 里的云计算设计模式_dapr_09

Dapr 允许通过链接一系列中间件组件来定义自定义处理管道。 请求在路由到用户代码之前经过所有已定义的中间件组件,然后在返回到客户机之前,按相反顺序经过已定义的中间件,如下图中所示。

浅析 Dapr 里的云计算设计模式_dapr_10

Actors

Actor 模型 起源于Carl Hewitt  在 1973 年提出的作为并发计算的概念模型,这种形式的计算会同时执行多个计算。 当时并没有高度并行的计算机,但多核 Cpu 和分布式系统的最新进步使得Actor 模型 变得流行。在Actor 模型中,Actor 是一个计算和状态独立的单元。 Actors 完全彼此隔离,它们永远不会共享内存。 Actors 使用消息相互通信。 当一个Actor 收到消息时,它可以更改其内部状态,并将消息发送到其他 (可能是新的) Actors。

Actor模型使得编写并发系统变得更简单的,它提供了基于 turn-based 的 (或单线程) 访问模型。 多个Actors可以同时运行,但每个Actor 一次只处理一个接收的消息。 这意味着,在任何时候,都可以确保在Actors 中最多有一个线程处于活动状态。 这使得编写正确的并发系统和并行系统变得更加容易。

Dapr 的实现基于 ​​项目 "Orleans" 中引入的虚拟Actor​​模式。 对于虚拟Actor模式,不需要显式的创建Actor。 第一次将消息发送到Actor时,Actor将被隐式激活并放置在群集中的节点上。 当不执行操作时,Actor 会以静默方式从内存中卸载。 如果某个节点出现故障,Dapr 会自动将激活的Actor 移到正常的节点。 除了在Actor之间发送消息以外,Dapr Actor模型还支持使用计时器和提醒调度将来的工作。

虽然Actor模型 提供了很大的优势,但必须仔细考虑Actor的设计。 例如,如果多个客户端调用相同的Actor,则会导致性能不佳,因为Actor  操作会按顺序执行。 下面的检查清单是是否适用于 Dapr Actor的一些标准:

  • 问题空间涉及并发性。 如果没有Actor,则需要在代码中引入显式锁定机制。
  • 可以将问题空间分区为小、独立和隔离的状态和逻辑单元。
  • 不需要低延迟的读取Actor 状态。  因为Actor 操作是按顺序执行,不能保证低延迟读取。
  • 不需要在一组Actor 之间查询状态。 跨Actor 的查询效率低下,因为每个Actor 的状态都需要单独读取,并且可能会导致不可预测的延迟。

满足这些条件的一种设计模式非常好,就是 ​​基于业务流程的 saga​​ 或 流程管理器 设计模式。 Saga 管理必须执行的一系列步骤才能达到某些结果。 Saga (或进程管理器) 维护序列的当前状态,并触发下一步。 如果一个步骤失败,saga 可以执行补偿操作。 利用Actor,可以轻松处理 saga 中的并发,并跟踪当前状态。 ​​EShopOnDapr 参考应用程序​​使用 saga 模式和 Dapr Actor来实现排序过程。

浅析 Dapr 里的云计算设计模式_设计模式_11

为了提供可伸缩性和可靠性,将在Actor服务的所有实例中对actor进行分区。 Dapr placement  服务负责跟踪分区信息。 启动Actor 服务的新实例时,Sidecar 会将支持的Actor 类型注册到placement 服务。 placement 服务计算给定Actor 类型的更新分区信息,并将其广播给所有实例。

关于 Actor Pattern 的信息以及相关论文:

总结

分布式架构的门槛比较高,需要考虑的问题很多,通常我们都需要考虑如下问题。

  1. ​服务治理​​:包含Service Invocation、Service Trusted and Authorization (服务的信任、认证与授权)、通信模式(HTTP / gRPC)、通信机制(Push / Pull)、状态管理(State Machine)
  2. ​运维​​:高可用、扩展机制、Log 处理、分布式追踪、Metric
  3. ​安全性​​:Data Encryption、Secret Management、KMS、Auth 集成
  4. ​性能和可靠性​​:Rate Limit、降级、熔断…
  5. ​可扩展的架构​
  6. ​如何提升开发团队的效能​

上述的这些东西,通常是一个有经验的、资深的软件工程师,如何在资源有限的情况下,可以快速开发、容易测试,是很多技术人的痛点所在。

这些问题从个别来看,都有相当成熟的系统,如果个别看,有很多现成的实践可以参考。但是对于存在了几十年的祖传代码的系统架构而言,如果要进行微服务改造,往往都要伤筋动骨,让技术主管和架构师伤透脑筋,往往要面对新旧技术的整合,同时也要面对现实的团队需求的交互和对于新技术的学习门槛。对于开发应用程式的开发人员来讲,满足业务需求的开发已经够头痛了,还要考虑这么多系统架构层面的东西,这种事是无法靠热情填补的。Dapr 将一些经过验证的技术和最佳实践带到微服务开发中。它通过即插即用模型将90 年代的数据驱动的客户端/服务器应用程序的操作,应用于现代云原生应用程序所需的最常见服务,让我们集中于业务需求的开发,而不需要考虑系统架构层面的东西 。

标签:服务,gRPC,Actor,Dapr,HTTP,设计模式,浅析,Sidecar
From: https://blog.51cto.com/shanyou/5790232

相关文章

  • 直播电商平台开发,设计模式单例模式
    直播电商平台开发,设计模式单例模式1.说明单例即只有一个实例,比如说配置、日志、连接池等,可以避免多个实例带来的多余的资源开销,并且在多线程环境下保证数据安全 2.类......
  • React核心技术浅析
    1.JSX与虚拟DOM我们从React官方文档开头最基本的一段HelloWorld代码入手:ReactDOM.render(<h1>Hello,world!</h1>,document.getElementById('root'));这段代......
  • 行为型设计模式之解释器模式
    解释器模式解释器模式属于行为型模式。它是指给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。是一种按照规定的语法(文法)进行......
  • 设计模式之原型模式
    概述在使用原型模式时,需要首先创建一个原型对象,再通过复制这个原型对象来创建更多同类型的对象。其定义如下:使用原型实例指定创建对象的种类,并且通过克隆这些原型创建新的......
  • 浅谈PHP设计模式的工厂模式
    简介工厂模式属于创建型模式,可以分为三种:简单工厂、工厂模式、抽象工厂。通俗讲就是用于如何优雅的创建对象而设计。当开发者不知道建什么对象,或者创建方式过于复杂的时......
  • 设计模式 - 桥接模式
    目录实例数据转换工具桥接模式概念角色定义典型代码具体实现总结源码实例数据转换工具Sunny软件公司欲开发一个数据转换工具,可以将数据库中的数据转换成多种文件格式,例......
  • 设计模式之抽象工厂模式
    简介工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会......
  • 模板方法设计模式
    模板方法设计模式什么是设计模式?某个问题的固定的解决方案。(可以被重复使用。)你知道哪些设计模式?GoF设计模式:通常我们所说的23种设计模式。(GangofFour:4人组提出的......
  • 一起学习 Go 语言设计模式之设计模式概述
    我的语言之局限,即我的世界之局限。——LudwigWittgenstein(1889-1951)设计模式的概念模式是在特定环境下人们解决某种重复出现问题的一套成功有效的解决方案。设计模式(Desi......
  • 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 浅析ASP.NET Core服务可用性
    使用Polly提高服务可用性什么是Pollyhttps://github.com/App-vNext/Pollyhttp://www.thepollyproject.orgPolly是一个.NET弹性和瞬时故障处理库,它允许开发者以流......