1.微服务架构发展历史
微服务架构发展大致有四个阶段:
- 第一代:服务治理等耦合代码之中
- 第二代:服务治理等以SDK的形式集成
- 第三代:Service Mesh(服务网格),相关技术:Istio、Linkerd。
- 第四代:多运行时微服务架构(别名Mecha/机甲),主要框架Dapr、Layotto(蚂蚁金服开源,MOSN 子项目,兼容Dapr协议)。
注,还有一些仁者见仁智者见智的看法:
- 也有人将 第一代、第二代 认为是一代
- Mecha是在Service Mesh基础上的进一步发展,是下一代 Service Mesh 的发展方向,所以也有人将其认为是同一代。
2.微服务的痛点
2.1.第一代(第二代)微服务架构
业务逻辑和非业务逻辑混合在一个进程内,应用既有业务逻辑,也有各种非业务的功能(体现为各种客户端SDK)。
带来的问题:
- 中间件能力相关代码侵入到了业务代码中,耦合性很高;
- 推动 RPC SDK 的升级成本非常高,进而也导致了 SDK 版本分化非常严重
- 同时这种方式对应用开发者的要求比较高,需要有丰富的服务治理的运维能力,有中间件的背景知识,使用中间件的门槛偏高。
2.2.Service Mesh(服务网格)
服务网格是一个基础设施层,用于处理服务间通讯。现代云原生应用有着复杂的服务拓扑,服务网格负责在这些拓扑中实现请求的可靠传递。 在实践中,服务网格通常实现为一组轻量级网络代理,它们与应用程序部署在一起,而对应用程序透明。

主要特征:
- 定位基础设施层
- 功能是服务间通讯
- 采用 Sidecar(边车) 部署
- 特别强调无侵入、对应用透明。
模型图:

绿色:应用程序 蓝色:Sidecar
基本思路:
在 Service Mesh 中,Sidecar 与应用程序部署在不同的进程中,不管 Sidecar 进行何种变化,应用程序对此都是是无感知的。
Service Mesh 将原来集成到 SDK 中的服务发现、负载均衡等分布式能力下沉到 Sidecar 中,通过 Sidecar 的流量劫持转发应用程序的请求,所有的服务都通过自己的 Sidecar 进行相互通信。
引入 Sidecar 之后,业务进程只专注于业务逻辑,无需关注服务发现等功能,但是依然还存在这一些问题:
- Service Mesh 的实现,本质是原协议转发。原协议转发可以给应用带来零侵入的优势,但是原协议转发也带来了一些问题,应用侧中间件SDK还需要去实现序列化和编解码工作,所以在多语言实现方面还有一定成本。
- 对于技术栈迭代升级,需要切换依赖的SDK或者是通过Service Mesh进行协议转换,成本较高。
2.3.Multi-Runtime(多运行时)架构
2020年,在“Multi-Runtime Microservices Architecture”文章中, Bilgin Ibryam 正式提出了 Multi-Runtime 的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华。Bilgin 总结了分布式应用存在的四大类需求,作为 Multi-Runtime 的理论出发点:

- 生命周期:主要是弹性伸缩和异常快速恢复的诉求
- 网络:可靠的网络、可靠的路由的需求
- 状态:对于服务编排、服务调度、状态管理等需求
- 绑定:与外部系统、中间件的通讯的需求
Service Mesh 架构将网络层抽出为独立的边车进程,而参考 Service Mesh 架构,Multi-Runtime 架构则是把各种边车提供的能力统一抽象成若干个 Runtime,这样应用从面向基础组件开发就演变成了面向各种分布式能力开发。
就个人理解,Runtime 就类似于接口,业务无需关注具体的分布式或者微服务的相关功能是使用什么组件或中间件实现的,这些中间件可以方便的被替换调。例如MQ,业务只需要使用 Runtime 提供的pubsub 能力即可,具体是使用Kafka、RocketMQ还是Pulsar无所谓,这些组件是可插拔的,能够快速替换。
生命周期管理类的需求主要是通过 PaaS 平台,如 Kubernetes 来满足,而 Service Mesh 提供的主要是网络中的点对点通讯,对于其他通讯模式典型如 pub-sub 的消息通讯模式并没有覆盖到,此外状态类和绑定类的需求大多都和 Service Mesh关系不大。
Mecha作为面向服务的分布式能力抽象层,是Service Mesh模式的自然进化版本,预计也将是云原生化和Mesh化的必然趋势,让我们将Mesh进行到底。
2.4.Mesh和Mecha对比
同为 sidecar 模式,但是和 Service Mesh 相比,Multi-Runtime 有自身的特点:
- 提供能力的方式和范围: Multi-Runtime提供的是分布式能力,体现为应用需要的各种分布式原语,并不局限于单纯的服务间点对点通讯的网络代理
- Runtime部署的方式: Multi-Runtime的部署模型,不局限于Sidecar模式,Node模式在某些场景下(如Edge/IoT,Serverless FaaS)可能会是更好的选择。
- 和App的交互方式: Multi-Runtime 和应用之间的交互是开放且有 API 标准的,Runtime 和 Micrologic 之间的“协议”体现在API上,而不是原生的TCP通讯协议。另外Multi-Runtime 不要求无侵入,还会提供各种语言的SDK以简化开发。

3.Dapr是什么?
Dapr是Distributed Application Runtime (分布式应用运行时)的缩写,是世界第一个分布式多运行时微服务架构,下一代 Service Mesh 的发展方向。2019年10月首次发布,之后在不到一年半的时间内,github star 数达到了 1.2 万,超过同期的 kubernetes、istio、knative 等,发展势头迅猛,业界关注度非常高。
Github:https://github.com/dapr/dapr
协议:Apache-2.0
Dapr GitHub首页的介绍是:
Dapr is a portable, event-driven, runtime for building distributed applications across cloud and edge.
Dapr是一种可移植的,事件驱动的运行时,用于构建跨云和边缘的分布式应用。
Dapr 是和平台无关的,这意味着可以在本地、Kubernetes 集群或者其它集成 Dapr 的托管环境中运行应用程序。在云平台和边缘计算中都能够运行微服务应用。
Any language, any framework, anywhere
历史:
前身可以认为来自Azure Service Fabric——一个由C++和C#写的开源 分布式任务平台,Dapr是Azure Service Fabric的超集,尤其是其中的Actor构建块,其api和Service Fabric基本保持一致。
2021.1.17,历时两年,Dapr正式发布,并于2021.11.3正式进入CNCF基金会,被称为第三(四)代微服务运行时。
**主要贡献者:**微软
**使用者:**微软、阿里云、高德地图、腾讯、钉钉、小红书、Man Group(全球最大的上市对冲基金集团)、富士通、NashTech(全球性IT外包提供商,越南第二大IT公司)、博世公司(其智能家居平台RIoT公司Home Connect Plus服务,可以控制来自不同品牌的设备和系统集中)
3.1.概念模型

3.1.1.Any language or any framework
最上层是目前Dapr所支持的语言,其中以.NET、Java和PHP支持最为完善。只要编程语言按照Dapr的标准实现SDK,Dapr即可对该语言提供支持。
同时,在多语言的环境下,使用极其方便,它以一种优雅的方式,简化的开发者和中间件的交互。例如同时有多种语言的应用接入MQ,这些应用只需要接入Dapr的SDK即可,不必单独对接相关语言的SDK。一些开源的中间件或者是平台等,通过Dapr提供的统一入口,可以快速接入各种语言,大大的提高生产力,比如OpenFunction FaaS框架,结合 KEDA 和 Dapr,实现对实际生产中大部分应用场景的覆盖。
3.1.2.API协议
Dapr Runtime 对外通过远程调用提供能力,支持 HTTP API 和 gRPC API 两种方式。Dapr与Dapr之间的调用能力,仅支持gRPC。也就是说,通过Dapr,我们甚至可以不用写RPC服务,业务进程可以直接通过gRPC调用远程的HTTP服务。


3.1.3.Building block (构建块)
中间蓝色的部分称之为“Building block (构建块 或构件)”,Dapr 为用户提供的 API,可以理解为Dapr可以为应用程序提供的功能。目前Dapr的构建块有8个:

服务调用
Endpoint:/v1.0/invoke
服务调用使应用程序能够通过 Http 或 gRPC 消息形式相互通信。 Dapr 提供了一个终结点(Endpoint),它充当反向代理与内置服务发现(基于k8s DNS or mDNS协议 or 自定义)的组合,同时内置分布式跟踪和错误处理。
特点:
1.
服务调用支持并发和限流控制(不区分 来自其他服务的直接调用、Pub/Sub事件、绑定事件等)
2.
支持显示请求正文大小,默认限制设置为 4 MB
3.
可搭配 OAuth 2.0 授权中间件
4.
内置简单的失败重试策略
状态管理
Endpoint:/v1.0/state
Dapr将actor的状态和有状态服务都的状态保存到的状态存储中。Dapr 提供基于key/value的状态 API ,使用可插拔的状态存储进行持久化。
默认是Redis本地存储,支持集群存储,包括Azure ComosDB、Cassandra、etcd、Memcached、MongoDB、ZooKeeper、AWS DynamoDB、Consul、PostgreSQL、SQL Server、MySQL等。
特点:
1.
支持基于ETag乐观并发(非全部组件都支持)
2.
默认最终一致性,支持强一致性
3.
支持简单的重试
4.
支持单、批量操作,并确保单个数据操作的事务隔离。如果组件不支持批量操作,Dapr内容会调用n次以完成(不保证全部成功)
5.
如果数据存储支持 SQL 查询,可以使用 SQL 查询 Actor 的状态
发布订阅
Endpoint:/v1.0/publish 、 /v1.0/subscribe
Dapr支持 at-last-once 的消息传递,可确保此消息至少传递给每个订阅者一次,默认基于Redis Stream来实现发布订阅,目前支持Redis Stream、Kafka、RabbitMQ、MQTT、Pulsar、AWS SNS/SQS、Azure Events Hub、Azure Service Bus等。
绑定
Endpoint:/v1.0/bindings
把应用程序的代码连接到不同的输入输出通道,提供一个外部云与本地服务或系统的双向连接。这样可以使的代码做到与平台无关。例如,代码部署到腾讯云平台,在应用触发报警事件的时候,使用钉钉进行消息推送。
支持Alibaba Cloud DingTalk binding spec、Apple Push Notification Service、AWS S3、AWS DynamoDB、Azure SignalR binding spec、Kafka、k8s事件、MQTT、PostgreSQL、MySQL、SMTP、本地存储等。
Actors
Endpoint:/v1.0/actors
Actor是孤立的独立计算单元,具有单线程执行。 Dapr提供了基于Virtual Actor模式的actor实现,该模式提供了单线程编程模型,并且在不使用actor时会对其进行垃圾回收。
可观测性
Dapr 集成了 OpenTelepetry,可以用以收集应用程序指标和分布式追踪。默认情况下,可以通过 zipkin 进行查看。
密钥存储(Secret stores)
Dapr 提供一个密钥构建块 API ,并且可以和本地环境变量、本地文件 与 Azure Key Vault、Kubernetes secrets 等集成,以存储机密信息。 服务代码可以调用密钥 API 从 Dapr 支持的密钥存储中检索密钥。
可以配置 Dapr 应用程序对密钥的CRD权限,通过定义allowedSecrets和/或deniedSecrets列表,可以限制应用程序仅访问特定的密钥。
Configuration
alpha中,由阿里敖小剑负责提案:https://github.com/dapr/dapr/issues/2941
3.1.4.Any where
最下层为目前支持 Dapr 的云平台或者边缘网络,由于每个能力都可以由不同的组件来完成,因此理论上只要 Dapr 的支持做的足够完善,就可以实现在任何平台上,甚至于WASM环境,总是能找到基于开源产品或者基于云厂商商业化产品的可用组件。
Dapr的定位分析:

- 定位:Dapr 将自身定义为运行时(runtime),而不是 Service Mesh 中的 proxy。
- 功能:Dapr为应用提供各种分布式能力,以简化应用的开发。例如:支持有状态和无状态、事件驱动、Pub/Sub。
- 多语言:对多语言的支持是 sidecar 模型的天然优势,Dapr 也不例外,考虑到 Dapr 为应用提交的分布式能力的数量,这可能比 Service Mesh 只提供服务间通讯能力对应用的价值更高。而且由于 Dapr 语言 SDK 的存在,Dapr 可以非常方便的和各编程语言的主流开发框架集成。
- 可移植性:Dapr 适用的场景包括各种云(公有云,私有云,混合云)和边缘网络,Multi-Runtime 架构的几个关键特性如”面向能力编程”、标准API、可运行时配置实现等为 Dapr 带来了绝佳的跨云跨平台的可移植性。
3.2.安全性
- 双向mTLS协议,加密 Dapr 实例之间的通信,并且证书会自动循环更新。
- 可控制服务访问白名单,只允许白名单内的服务进行本服务的调用。
- 可配置Dapr sidecar能够使用的api白名单
- OAuth 2.0授权中间件
- 可以配置每个API请求都需要携带token
- 限流中间件
- Dapr sidecar 和 app 之间通信加密:已列入 roadmap
3.3.Dapr和服务网格的对比
Dapr:“许多人都说我是 Service Mesh,但我不是!我是 Service Mesh 下一代的发展方向”。
Service Mesh 工作在基础设施层,以便管理服务之间的流量,但是Dapr还提供了状态管理等构件块,是工作在应用层的,可能称之为“应用网格”会更加贴切。此外,Dapr可以和现有的 Service Mesh 的sidecar 同时使用,但是流量会多一层跳转,应用的流量会先进入Dapr,再进入 Service Mesh 的边车,并且在应用程序的另外一端以相反的顺序流过栈 。
以下内容摘自:https://docs.dapr.io/zh-hans/concepts/service-mesh/
Dapr 专注于提供构建基块,使开发人员更容易将应用程序构建为微服务。Dapr 以开发人员为中心,而服务网格以基础设施为中心。
在大多数情况下,开发人员不需要意识到他们正在构建的应用程序将部署在包括服务网格在内的环境中,因为服务网格会拦截网络流量。 服务网格主要由系统操作员管理和部署。 但是,Dapr 构建块 API 旨在供开发人员在其代码中明确使用。
Dapr 与服务网格都有的一些常见功能包括:
- 基于 mTLS 加密的服务到服务安全通信
- 服务到服务的度量指标收集
- 服务到服务分布式跟踪
- 故障重试恢复能力

重要的是,Dapr 以开发人员为中心,提供了通过名称进行服务发现和调用的方式。 也就是说,通过 Dapr的服务调用 API,开发人员使用服务名称进行调用,而服务网格则需处理网络概念,如 IP 和 DNS 地址。 但是,Dapr不提供路由或流量分配等关于流量控制的功能。 流量路由通常在应用程序的入口代理中处理,不必使用服务网格。 此外,Dapr还提供了其他应用级别的构建块,如状态管理、发布/订阅 、参与者等。
3.4.托管环境
Dapr可以托管在多个环境中,包括在Windows/Linux/macOS机器上自托管和Kubernetes。
3.4.1.自托管
自托管模式下,每个运行的服务都有一个 Dapr 运行时进程 (或 sidecar,即daprd) ,在应用代码中可以通过 HTTP 或 gRPC 调用它。

3.4.2.Kubernetes 托管
在托管在容器环境中(如 Kubernetes),Dapr作为 sidecar 容器运行,和应用程序容器在同一个 pod 中。
在 Kubernetes 中, dapr-sidecar-injector 和 dapr-operator 服务提供一级的集成,以将 Dapr作为 sidecar 容器启动在与服务容器相同的 pod 中 ,并为在集群中部署的 Dapr组件提供更新通知。

3.5.不足
- 仅支持HTTP和gRPC协议。dapr默认认为,主应用是个Web服务或者是gRPC服务。
- 服务治理能力不是很丰富,对网络流动控制,不如Service Mesh更加精细。
- 调试不方便,一般需要通过附加到已经运行的应用程序来实现debug。
- 比直接在应用间进行服务调用,性能有所下降。但是在Service Mesh的方案中,一样会有性能下降。
- 使用之后如果想要去除Dapr,可能会比较麻烦。
4.Dapr学习
在线体验:https://start.aliyun.com/course?id=gImrX5Aj
Dapr 官方站点:https://docs.dapr.io/zh-hans/
微软微服务示例:https://github.com/dotnet-architecture/eShopOnDapr
中文书籍:Dapr学习手册
公众号:Dapr分布式运行时
手把手教你学Dapr系列:https://xie.infoq.cn/article/07551649ed0ddbf57034474cd
Dapr学习笔记(敖小剑):https://skyao.io/learning-dapr/docs.html
5.参考
- Dapr:我不是 Service Mesh!我只是长得很像:https://xie.infoq.cn/article/950b7ede0479f9f337b4bf2a9
- 开源微服务运行时 Dapr 发布 1.0 版本:https://www.infoq.cn/article/m1hMST70ck2VB3GKNM39
- Dapr v1.0展望:从servicemesh到云原生:https://skyao.io/talk/202103-dapr-from-servicemesh-to-cloudnative/
- Service Mesh:下一代微服务:https://skyao.io/talk/201710-service-mesh-next-generation-microservice/
- Dapr 文档库:https://docs.dapr.io/zh-hans/
- 单体应用 适合采用 dapr 构建吗?:https://www.cnblogs.com/shanyou/p/15412779.html
- 使用 Dapr 缩短软件开发周期,提高工作效率:https://www.cnblogs.com/shanyou/p/15840916.html