dapr知多少|分布式应用运行时

格格巫MMQ!! 格格巫MMQ!!     2022-11-29     321

关键词:

Intro
Dapr 官方团队已于最近(2021.2.17)正式发布Dapr v1.0,Dapr已正式生产可用,可以部署到自托管环境或 Kubernetes 集群。对于绝大多数开发者来说,想必对Dapr只是有所耳闻,而具体是什么(What),可以解决什么样的问题(Why&How),有怎样的应用场景(Where),并不知悉。本文就尝试简要梳理下Dapr,并尝试回答以上问题。

What’s Dapr
Distributed Application Runtime. An event-driven, portable runtime for building microservices on cloud and edge.
分布式应用运行时。一个事件驱动、可移植的运行时用于在云上和边缘计算上构建微服务。

以上是Dapr官方GitHub仓库上对Dapr的简介。文字虽短,口气却很大,因为其除了涵盖了当前所有的技术热点:分布式、云、微服务,还自我标榜为:分布式应用运行时。分布式应用我们或多或少有些了解,运行时也听到不少,比如常见的语言运行时:Java 运行时,.NET 运行时,Go 运行时等等,那运行时又是什么东西?简要来说:运行时是程序运行依赖的执行环境。以.NET 程序运行时CLR为例,它为.NET应用程序提供了一个托管的代码执行环境负责应用程序在整个执行期间的内存管理、线程管理、安全管理、远程管理、即时编译等。

那分布式应用运行时,就是提供分布式应用运行所依赖的的执行环境。那运行分布式应用需要哪些环境依赖呢?回答这个问题,我们要先思考开发分布式应用的挑战是什么?明确了挑战,那就找到了答案。

从单机到分布式,是追求更快和更高的性能,但也带来了更多的不确定性。比如,不确定计算机何时异常,不确定磁盘何时损坏,不确定网络通信的延迟,也不确定消息是否被正常消费。这些不确定性构成了分布式应用的挑战,简而言之:

异构的机器与网络:稳定性问题
普遍的节点故障:可靠性问题
不可靠的网络:一致性问题
面对这些挑战,业界提出了诸多的分布式理论、协议,如CAP定理,BASE理论,一致性协议2PC/3PC/ZAB,来保证系统的正常运行。虽然问题貌似是有了解决方案,但是应用的复杂度升高了。应用除了需要实现业务需求,还要兼顾非业务需求,集成诸如服务发现、负载均衡、失效转移、动态扩容、数据分片、调用链路监控等分布式系统的核心功能,对应用有很强的侵入性,这就是以Spring Cloud为代表的微服务框架的常见做法。

那如何解决侵入性的问题呢?这个问题随着容器编排技术的成熟有了新的解法。Kubernetes可以不侵入应用层,在容器层解决问题,比如K8S Service就具有服务发现、负载均衡的能力,HPA具有动态扩容的能力。随着K8S的快速发展,云原生的概念,也就越来越深入人心,那如何利用好K8S提供的基座能力,将更多的分布式能力下沉,让应用开发回归业务呢?其中Service Mesh提出的Sidecar模式,就很好的解决了微服务架构中网络通信的问题。Sidecar主要就是用来处理诸如服务发现、负载均衡、请求熔断等一系列非业务需求,应用在部署时动态插入Sidecar,服务间的通信通过Sidecar进行代理,以完成对服务间网络通信的接管。

到这里,微服务开发在Service Mesh的帮助下,已经渐渐回归业务本身,让更多的开发者看到了一丝曙光。It’s enough? 来看下Bilgin Ibryam在Multi-Runtime Microservices Architecture文章中提及的分布式应用的四大需求:

分布式应用的四大需求

从上图可以看出,除了网络(Networking)外,生命周期(Lifecycle)、状态(State)、捆绑(Binding)也是分布式应用要解决的问题之一。网络问题可以借由Service Mesh 比如Istio予以解决。那其他三个该如何解决呢?又要应用自行开发集成吗?显然不符合应用回归业务本身的诉求。这时,Dapr登场了,Dapr提出的分布式应用运行时就是实现了以上四个需求并将其下沉作为分布式应用的运行环境。

简而言之:Dapr将分布式能力进行封装下沉作为运行时以简化分布式应用开发的技术复杂度。

How Dapr Works
那Dapr如何简化分布式应用的开发呢?下面我们来看一看Dapr的主要特性。
Any language, any framework, anywhere

一图胜千言:Dapr通过以HTTP/gRPC API这种与语言无关的方式暴露封装的分布式能力供应用调用,从而支持使用任意语言或框架进行开发集成。目前官方已经提供了Go,Node,Python,.NET,Java, C++,PHP,Rust,Javascript的Sdk,简化Dapr的集成。

其中Dapr的核心构建块(Building Block)就是用来提供各种不同的分布式能力,我们来分别看一看。
Building Block

  1. Service-to-service invocation(服务调用)
    提到跨服务方法调用,这个大家肯定会想,这简单啊,不就是服务暴露API就好了嘛。是,但不完全是。比如nodeapp暴露了一个API:http://10.0.0.2:8000/neworder,按照传统的方式,直接HTTP POST这个API访问就得了,但在Dapr中,其提供了服务间方法调用的接口规范,需要按照
    POST/GET/PUT/DELETE http://localhost:/v1.0/invoke//method/的格式进行访问。那假设pythonapp需要访问nodeapp的方法,就需要POST一个请求到http://localhost:3500/v1.0/invoke/nodeapp/method/neworder。你可能会想为何多此一举呢?此举的意义何在呢?目的很简单,就是为了实现对服务间网络通信的控制以完成诸如服务发现、流量控制、重试熔断、安全访问等,而这相关的网络控制功能就是集成在Dapr的Sidecar中,以对应用透明的方式集成进来的。整体的服务调用流程如下图所示:
    服务间调用

PS:如果对Istio熟悉的同学需要注意,二者虽然都是通过Sidecar的模式进行网络控制,但二者是有有区别的。Dapr是以API的方式,而Istio是以代理的方式(不改变HTTP请求URI)。

  1. State management(状态管理)
    在进行微服务开发时,绕不开的话题就是服务间的状态共享、并发一致性问题。对于状态共享,你可能会说,各个服务连接到同一个Redis实例就OK了。是,但不得不考虑潜在的更新冲突的问题。Dapr 以更友好的HTTP API的方式进行状态的存储和读取,同时支持通过ETags进行并发控制,并支持通过选项设置并发和一致性行为。

存储:POST http://localhost:/v1.0/state/
读取:GET http://localhost:/v1.0/state//
删除:DELETE http://localhost:/v1.0/state//
以下是保存状态的举例:

concurrency用于指定并发选项:first-write-wins/last-write-wins(以第一次写入为准/以最后一次写入为准),默认以最后一次写入为准。
consistency用于指定一致性选项:strong/eventual(强一致性/最终一致性),默认为最终一致性。
curl -X POST http://localhost:3500/v1.0/state/starwars
-H “Content-Type: application/json”
-d ‘[

“key”: “weapon”,
“value”: “DeathStar”,
“etag”: “xxxxx”,
“options”:
“concurrency”: “first-write”,
“consistency”: “strong”


]’
目前支持使用Azure CosmosDB、 Azure SQL Server、 PostgreSQL,、AWS DynamoDB、Redis 作为状态存储介质。

  1. Publish and subscribe(消息发布及订阅)
    发布订阅模式,老生常谈了,主要是用于微服务间基于消息进行相互通信。你可能也会说,这也要拿出来说,我搞个RabbitMQ/RocketMQ就是了。是的,但我还是要说,Dapr提供了一致性的消息发布、订阅API,而无需关注具体使用的是何种Message Broker,从而和底层基础设施解耦。

发布:POST http://localhost:/v1.0/publish//[? ]
获取可订阅主题:GET http://localhost:/dapr/subscribe
订阅:POST http://localhost:/
发布订阅

  1. Resource bindings and triggers (资源绑定及事件触发)
    Dapr的Bindings与Azure Functions很类似,其是建立在事件驱动架构的基础之上的。通过建立触发器与资源的绑定,可以从任何外部源(例如数据库,队列,文件系统等)接收和发送事件,而无需借助消息队列,即可实现灵活的业务场景。Dapr的Bindings分为两种:

Input Bindings(输入绑定):当外部资源的事件发生时,借助输入绑定,你的应用即可通过特定的API:POST http://localhost:/收到外部资源的事件,用于处理特定逻辑。
Output Bindings(输出绑定):输出绑定允许你调用外部资源。比如,在订单处理场景中,在订单创建成功后,可以将订单信息通过Dapr的绑定API:POST/PUT http://localhost:/v1.0/bindings/输出到Kafka特定队列上。
资源绑定及事件触发

  1. Actors
    Dapr中的Actor模型,和Orleans的Virtual Actor一脉相传,之前写过一篇文章Orleans 知多少 | .NET Core 分布式框架介绍过。简单来讲:Actor模型 = 状态 + 行为 + 消息。一个应用/服务由多个Actor组成,每个Actor都是一个独立的运行单元,拥有隔离的运行空间,在隔离的空间内,其有独立的状态和行为,不被外界干预,Actor之间通过消息进行交互,而同一时刻,每个Actor只能被单个线程执行,这样既有效避免了数据共享和并发问题,又确保了应用的伸缩性。

Actor模型大大简化了并发编程的复杂度,Dapr在Actor运行时中提供了许多功能,包括并发控制,状态管理,生命周期管理如Actor的激活/停用以及用于唤醒Actor的Timer(计时器)和Reminder(提醒)。这些功能同样也是通过API的方式予以提供。

调用Actor 方法:POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors///method/
创建 Timer:POST/PUT http://localhost:3500/v1.0/actors///timers/
创建 Reminder:POST/PUT http://localhost:3500/v1.0/actors///reminders/
6. Observability(遥测)
Dapr记录指标,日志,链路以调试和监视Dapr和用户应用的运行状况。 Dapr支持分布式跟踪,其使用W3C跟踪上下文标准和开放式遥测技术,可以轻松地诊断在生产环境中服务间的网络调用,并发送到不同的监视工具,如Prometheus。

  1. Secrets(安全)
    Dapr 提供了Secret管理,不过不同于K8S中的Secret,其支持与公有云和本地的Secret存储集成,以供应用检索使用。

What Can We Do With Dapr
了解了Dapr是什么,以及其提供的特性,那Dapr的应用场景就一目了然了。也就是官网首页的Slogan:Simplify cloud-native application development–Focus on your application’s core logic and keep your code simple and portable。
简化云原生应用的开发,确保应用专注于业务,并保证代码简单可移植。

因此,在考虑云原生应用开发的技术选型时,尽情尝试吧,目前在国内阿里云也已采用。

Last
在云原生如火如荼发展之际,Dapr V1.0 的正式发布,为开发者指明了云原生时代微服务的开发方向。

dapr牵手.net学习笔记:开篇

dapr,一个为分布式应用程序的运行时,为开发者在对接分布式组件时,提供了便利。使用dapr带来的好处可扩展性,因为它是通过sidecar的理概念来集成其他运行时的。同时dapr还提供了多种语言的SDK。关于dapr更多... 查看详情

微服务的终极目标,mecha分布式运行时之dapr

查看详情

微服务的终极目标,mecha分布式运行时之dapr

查看详情

dapr简介(代码片段)

...服务构件3.展望!dapr简介Dapr(DistributedApplicationRuntime)分布式应用运行时1Dapr是什么?Daprisaportable,event-drivenruntimethatmakesiteasyfordeveloperstobuildresilient,microservicestatelessandstatefulapplicationsthatrunonthecloudandedgeandembracesthediversityoflanguagesanddev... 查看详情

dapr中国社区活动之分布式运行时开发者日(2022.09.03)

...首次发布以来,Dapr(DistributedApplicationRuntime,分布式应用运行时)因其“更稳定”、“更可靠”、“更一致”、“更简单”,吸引了大量的关注和喜爱,至今在GitHub上已有近1.9万Stars,俨然已成为开发... 查看详情

微服务的扫地僧--dapr中文v1.5发布!

...位对云原生和微服务框架感兴趣的童鞋一定不能错过这个分布式应用程序运行时。我们翻译小组也是希望通过对Dapr文档中文的支持,让Dapr在华语的云原生社区更好地推广开来,欢迎各位使用Dapr,参与到Dapr以及云原生开源社区... 查看详情

dapr集成flomesh实现跨集群服务调用(代码片段)

...地以独立运行时的方式从应用程序分离出来。这其中就有分布式应用运行时和服务网格两种运行时,今天这篇文章就为大家介绍Dapr与Flomesh服务网格的集成进行跨集群的服务调用来实现“真正的”多集群互联互通。多集群Kuber... 查看详情

微服务的终极目标,mecha分布式运行时之dapr

1.Mecha是啥?微服务发展到今天,已经有很多公司多年前已经改造完毕,也有些公司还在路上,微服务的优势,有过了解的朋友应该也都能说出个一二三来,经历过微服务改造的,应该都知道其中的艰辛... 查看详情

dapr+.net实战服务监测

服务监测分布式服务性能指标,链路追踪,运行状况,日志记录都很重要,我们日常开发中为了实现这些功能需要集成很多功能,替换监控组件时成本也很高。Dapr可观测性模块将服务监测与应用程序分离。它... 查看详情

云原生开发框架dapr环境搭建:cli安装和初始化

...istributed Application Runtime,中文要翻译的话就是:分布式应用运行时。也就是一个运行时框架,面向云原生架构。dapr官网地址:Dapr-DistributedApplicationRu 查看详情

dapr初识

...(DistributedApplicationRuntime)是微软于2019年10月16日首次发布的分布式程序运行时,到现在已经过去2年多,从最初的v0.1.0到现在的v1.0.0-rc2,加入了好多新的功能。支持的中间件越来越多,基本上主流的中间件(本地版和各云提供商的托... 查看详情

dapr+.netcore实战服务调用(代码片段)

服务调用是什么在分布式应用程序中的服务之间进行调用会涉及到许多挑战。例如:维护其他服务的地址。如何安全地调用服务。在发生短暂的暂时性错误时如何处理重试。分布式应用程序调用链路追踪。服务调用构建块通... 查看详情

daprv1.9.0版本已发布

...保开发人员专注于编写业务逻辑,而不必分神于解决分布式系统难题,由此显著提高生产力并缩短开发时长。Dapr 是用于构建云原生应用程序的开发人员框架,可以更轻松帮助开发人员在Kubernetes上构建运行 查看详情

单体应用适合采用dapr构建吗?

...行的系统就叫做巨石型应用),但是它却用到了分布式中间件 查看详情

dapr+.netcore实战状态管理(代码片段)

状态管理解决了什么分布式应用程序中的状态可能很有挑战性。例如:应用程序可能需要不同类型的数据存储。访问和更新数据可能需要不同的一致性级别。多个用户可以同时更新数据,这需要解决冲突。服务必须重试 ... 查看详情

ncf的dapr应用实例的运行(代码片段)

...以轻松构建在云和边缘上运行的弹性、无状态和有状态的应用程序,并包含语言和开发人员框架的多样性。任何语言,任何框架,任何地方今天,我们正在经历一波云采用浪潮。开发人员对Web+数据库应用程序... 查看详情

ncf的dapr应用实例的运行

简介先上一篇张队的文章让大家了解一下Dapr的真容:https://www.cnblogs.com/shanyou/p/16246991.html看完上述文章,我们大家需要有一个共识的概念就是,Dapr它是边车模式,下图中箭头所指的地方就是边车,是不是一下子就知道Dapr是什么... 查看详情

手把手教你学dapr-9.可观测性(代码片段)

...Metrics(指标)、Logs(日志)和Health(运行状况)监控应用程序。分布式跟踪Dapr使用Zipkin协议进行分布式跟踪和Metrics收集。由于Zipkin协议的普遍性,许多后端都是开箱即用的,例如Stackdriver、Zipkin、NewRelic等。结合OpenTelemetryCollecto... 查看详情