Dapr
Dapr(Distributed Application Runtime,分布式运行时) ,是微软内部团队的一个开源项目。Dapr 同样使用Sidecar 架构,以独立进程的形式与应用程序同时运行,同时兼具Service Mesh 中Sidecar/Proxy 的优点和高度可扩展的特性。Dapr 主要有两大特性:一个是跨语言、多运行环境支持(Any language,anywhere) ,一个是组件的可插拔、可替换。应用开发者可以基于Dapr 多语言的SDK 面向Dapr 的分布式能力进行编程,通过集成Dapr 的SDK ,可以使用任何语言、任何框架构建自己的微服务应用,并将应用运行在任何有Dapr 的环境中。
同时Dapr 也可以部署在任何环境里面,包括自己本地的环境、边缘计算的场景、拥有K8s 的环境或者是任何的商业化云产品开发厂商的环境中。
在K8s 的环境中,Dapr 和应用程序运行在同一个Pod 里,但是在不同的容器中。Dapr 的构建块则分布在其他的Pod 中,通过yaml 文件的方式进行激活并让Dapr 感知到。
在构建微服务应用时,每个组件都是独立的。开发人员可以采用其中一个或多个或全部来构建应用,并且组件的更新对应用来说是无感知的,应用程序不会感知到底层组件的升级。这也就是Dapr 的第二个特性:组件的可插拔、可替换特性。Dapr 通过把一些构建微服务应用所需的最佳实践内置到开放、独立的构建块(building block)中,让开发人员只需专注于业务逻辑代码的编写,即可开发出功能强大的微服务应用,截至现在,Dapr 社区中已经有70 多个组件可供开发人员进行使用。
设计理念
Multi-Runtime(运行时)软件架构
Multi-Runtime(运行时)架构是一种未来架构趋势,Dapr 便是基于此架构,从需求出发,分布式应用的主要需求包括以下四大类:
生命周期:主要是弹性伸缩和异常快速恢复的诉求
网络:可靠的网络、可靠的路由的需求
状态:对于服务编排、服务调度、状态管理等需求
绑定:与外部系统、中间件的通讯的需求
在此需求基础上,Service Mesh 架构将网络层抽出为独立的边车进程,而参考Service Mesh 架构,Multi-Runtime 架构则是把各种边车提供的能力统一抽象成若干个Runtime ,这样应用从面向基础组件开发就演变成了面向各种分布式能力开发。
Mesh
Service Mesh 的发展为我们指明了一个发展方向:将SDK 中的分布式能力外移到独立的Sidecar 中。但是我们可以想象一下,在未来是否可以将我们现在集成的中间件能力也外移到独立的Sidecar 中呢?比如说将数据库Mesh 化、将消息中间件Mesh 化、将缓存Mesh 化,将除了业务代码程序之外的全部SDK 都Mesh 化。
我们可以将这些独立出来的Mesh 化模块统称为提供不同功能的“运行时”组件。过多的“运行时”组件出现之后,应用程序在运行时就会依赖一个或多个这样的Mesh 化模块。虽然做到了将SDK 移出了应用程序,但是这种多依赖的结果显然不是我们所期望的形式。Dapr 的出现将这些提供不同分布式能力以及中间件能力的“运行时”模块进行了整合,开发人员可以按照自己的需求,通过yaml 文件的方式,将提供不同功能的组件整合到Dapr 的构建块(Building Block)中。应用程序可以通过Dapr 提供的标准API ,访问构建块来获得并使用这些能力。
在K8s 环境中,应用程序代码和Dapr 的Sidecar 分别运行在两个不同的容器中。应用程序代码可以通过标准的HTTP/gRPC 协议使用Dapr 提供的各种分布式能力,而Dapr 中提供能力的构建块(Building Block)又是可以根据开发人员的需求进行可插拔和高度扩展的。
Dapr 的这种模式极大的提升了Service Mesh 体系中Sidecar 的灵活性,并对各种不同的Mesh 进行了统一的整合。可以说Dapr 的这种模式是未来Service Mesh 未来发展的一种新方向。
功能和架构
Dapr 虽然也使用Sidecar 架构,但是却提供了更多的能力和使用场景。除了提供和Service Mesh 一样的服务间远程调用(Service-to-service invocation)能力外,还提供了状态管理(State management)的能力来帮助开发人员构建出弹性的、有/ 无状态的应用程序,并且提供了发布订阅(Publish and subscribe) 、资源绑定(Resource bindings)等额外的能力。
Dapr 中所有功能都是通过使用Dapr 中的构建块(Building Block)来进行提供。下图中蓝色方框中的内容,都是Dapr 目前已经提供给应用开发人员使用的构建块。
在Dapr 的架构中,有三个主要的组成部分:Dapr API、构建块(Building Block)和组件(Component) ,他们之间的关系如下图所示。
应用程序可以通过标准的Dapr API 与构建块进行通信,构建块作为Dapr 对外提供分布式能力的基本单元,将各种分布式能力进行了抽象,并将自己内部整合的分布式能力提供给应用程序。组件(Component)是构建块的具体实现,每个构建块都是由一个或多个组件组成,并且所有的组件都是可插拔和高度扩展的。Dapr 内部有自己的一套SPI 扩展机制,任何开源的或者商业化的产品都可以很方便的集成到一个组件中。
例如想要将一个Redis 集成到Dapr 中,只需要将Redis 集成到一个State 的组件中就可以很方便的在应用程序中通过HTTP/gRPC 协议使用Redis 的功能,而不需要在应用程序中依赖操作Redis 的SDK 。
Dapr 的主要架构可以总结为以下三点:
Dapr API 通过标准的HTTP/gRPC 协议对外暴露构建块的能力。
构建块则对分布式能力进行一个抽象,并提供各种分布式运行时能力
组件是构建块能力的具体实现者。
应用开发者只需要基于Dapr 多语言的SDK ,并且面向能力的方式对Dapr 进行编程,而底层的具体实现方式由Dapr 以yaml 文件的方式进行激活。应用无需感知到自己使用的分布式能力是由哪种方式实现的。Dapr 整体的功能图如下图所示。
Dapr 与Service Mesh
虽然Dapr 和Service Mesh 在架构上都是使用的Sidecar 模式,并且在功能上也存在一些重叠部分,但是不能将Dapr 简单的定义为Service Mesh 。
Service Mesh 主要专注于服务调用和网络问题,而Dapr 是为了给应用服务提供更多的 分布式能力 而诞生的,两者的关注点在本质上就不一样。Service Mesh 主要以基础设施为中心:
Service Mesh 更加聚焦于网络问题的处理,通过拦截网络流量,可以使应用程序无感知的部署在包含Service Mesh 的环境中。
Service Mesh 主要由系统操作员进行管理和部署,使Service Mesh 更像是一种特殊的“基础设施”。开发人员无需考虑一些其他的细节,因为Service Mesh 已经将网络概念扁平化。
Service Mesh 通过按照原协议转发的方式来进行流量拦截,可以给业务系统带来零侵入的体验。
与Service Mesh 不同,Dapr 是以开发人员为中心:
当开发人员在代码中需要使某种分布式能力时,开发人员需要明确调用Dapr API 。Dapr 为开发者提供了标准的分布式API ,这种API 带来了多语言的、面向能力的、统一的编程体验。
Dapr 提供了应用级别的构建块(Building Block)和70 多种分布式能力的抽象集成,使得开发人员更容易将应用程序构建为弹性的微服务。
Dapr 通过采用多语言SDK+ 标准API+ 各种分布式能力的方式为应用程序提供服务。
Links