【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

重磅!微软开源微服务构建软件 Dapr

  • 2019-10-17
  • 本文字数:4644 字

    阅读完需:约 15 分钟

重磅!微软开源微服务构建软件Dapr

随着越来越多的开发人员构建可扩展的云原生应用,利用托管服务来部署和运行这些云原生应用。在过去几年中,这一转变值得人们关注。随着这一转变,微服务架构已经成为构建云原生应用的标准,预计到 2022 年,将有 90% 的新应用采用微服务架构。微服务架构提供了极具说服力的好处,包括可扩展性、松散的服务藕合和独立部署等,但这种方法的成本可能很高,因为开发人员需要了解和熟练掌握分布式系统。


开发人员希望专注于业务逻辑,频繁且增量地迁移遗留代码,同时依靠平台为他们的应用提供所需的规模、弹性、可维护性、灵活性和云原生架构的其他属性。然而,开发人员发现,在云端和边缘之间的可移植性有限,他们不断地解决相同的分布式系统问题,如状态管理、弹性方法调用和事件处理。此外,许多编程运行时通常具有狭隘的语言支持和严格控制的特性集,这使得构建微服务架构变得具有挑战性。


为了使所有开发人员能够使用任何语言和框架轻松地构建可移植的微服务应用,无论是编写新代码还是迁移现有代码,我们很高兴地宣布将 Dapr 开源。

构建事件驱动、无状态和有状态的应用

例如,在构建由多个服务组成的电子商务应用时,你可能希望使用有状态的角色来表示购物车服务,并为支付和配送服务调用无状态函数。编写这个应用可能涉及到使用多种语言、开发框架和基础架构平台,以及与外部服务集成。而理解和管理如此复杂的技术栈,会分散开发人员对构建业务价值的注意力。


Dapr:云端和边缘的微服务构建块

Dapr 是开源的、可移植的、事件驱动的运行时,它使开发人员可以轻松地构建弹性的、微服务的无状态和有状态的应用,这些应用运行在云端和边缘之上。Dapr 支持所有编程语言和开发框架的多样性,并简化了构建应用的过程(如电子商务应用)。


Dapr 是由一组标准 HTTP 或 gRPC API 访问的构建块组成,这些构建块可从任何编程语言调用。这些构建块为所有开发人员提供了经过验证的行业最佳实践,并且每个构建块都是独立的;你可以在应用中使用其中一个、一些或者全部构建块。此外,通过开源项目,我们欢迎社区添加新的构建块,并向现有构建块中贡献新的组件。Dapr 与平台完全无关,这意味着你可以在任何 Kubernetes 集群上,以及 Dapr 集成的其他托管环境中本地运行应用。这使得开发人员能够构建可以同时在云端和边缘上运行的微服务应用,而无需更改代码。


通过在标准 API 上调用 Dapr 构建块,使用任何语言和框架来构建应用。


Dapr 构建块的 alpha 版本

在设计和构建微服务应用时需要许多功能。在 Dapr 的第一个开源 alpha 版本中,我们着重于提供一些最常用的构建块。


  • 服务调用: 弹性服务与服务之间(service-to-service)调用可以在远程服务上启用方法调用,包括重试,无论远程服务在受支持的托管环境中运行在何处。

  • 状态管理: 通过对键 / 值对的状态管理,可以很容易编写长时间运行、高可用性的有状态服务,以及同一个应用中的无状态服务。状态存储是可插入的,并且可以包括 Azure Cosmos 或 Redis,以及组件路线图上的其他组件,如 AWS DynamoDB 等。

  • 在服务之间发布和订阅消息: 使事件驱动的架构能够简化水平可扩展性,并使其具备故障恢复能力。

  • 事件驱动的资源绑定: 资源绑定和触发器在事件驱动的架构上进一步构建,通过从任何外部资源(如数据库、队列、文件系统、blob 存储、webhooks 等)接收和发送事件,从而实现可扩展性和弹性。例如,你的代码可以由 Azure EventHub 服务上的消息触发,并将数据写入 Azure CosmosDB。

  • 虚拟角色: 无状态和有状态对象的模式,通过方法和状态封装使并发变得简单。Dapr 在其虚拟角色(Virtual Actors)运行时提供了许多功能,包括并发、状态、角色激活 / 停用的生命周期管理以及用于唤醒角色的计时器和提醒。

  • 服务之间的分布式跟踪: 使用 W3C 跟踪上下文(W3C Trace Context)标准,轻松诊断和观察生产中的服务间调用,并将事件推送到跟踪和监视系统。

用于可移植性和可扩展性的标准 API

那么,如何使用这些 Dapr 构建块呢?例如,假设你正在已部署到 Kubernetes 集群中的微服务应用中使用 Azure Functions 运行时,你希望利用 pub/sub 模式在服务之间发送消息。现在,Azure Functions 运行时尚未内置这种功能,但通过在 http 上使用 Dapr pub/sub 构建块,你可以轻松添加这个新功能。于是你有了新的开发能力!


此外,Dapr pub/sub 构建块具有可插入的组件模型,这意味着你可以动态选择不同的实现来发送消息,而无需更改任何代码。例如,你可以根据自己的喜好来选择 Redis、Kafka 或 Azure Service Bus pub/sub Dapr 组件。在这两种情况下,代码都保持不变,包括通过使用标准 API 在不同的受支持的基础设施之间进行移植。


为了实现可移植性与现有代码的轻松集成,Dapr 通过 http 或 gRPC 提供标准 API。以 pub/sub 为例,下面的节点代码现实如何使用“http://<myappaddress>/dapr/subscribe”端点订阅名为“A”和“B”的主题,然后在消息发布到这些主题时通知你的应用。


const express = require('express');const bodyParser = require('body-parser');const app = express();app.use(bodyParser.json());const port = 3000;app.get( '/dajgr/subscribe', (_req, res) => {    res.json([        'A',        'B'    ]);});app.post('/A', (req, res) => {    console.log("A:", req.body);    res.sendStatus(200);});app.post('/B', (req, res) => {    console.log("B:", req.body);    res.sendStatus(200);});app.listen(port, () => console.log('Node App listening on port ${port}!'))
复制代码


为了进行比较,下面是用 C# 编写的相同代码,使用的是从 ASP.NET Core CreateWebHostBuilder() 调用的UseStartup() 处理程序。


using System.Collections.Generic;using System.Text.Json;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Dependencylnjection;using Microsoft.Extensions.Hosting;using System.IO;namespace DaprPubSub{    public class Startup    {        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)        {            app.UseRouting();            app.UseEndpoints(endpoints =>            {                // Route called by Dapr runtime to get topics this app subscribes to.                endpoints.MapGet("dagr/subscribe", async context =>                {                    // Returns list of topics to subscribe to as json in response.                    var topicsToSubscribe = new List<string>() { "TopicA", "TopicB" >;                    await JsonSerializer.SerializeAsync(context.Response.Body, topicsToSubscribe);                });                                // Route to handle events published to TopicA                endpoints.MapPost("A", async context =>                {                    // Read the event form request body.                    using (var streamReader = new StreamReader(context.Request.Body))                    {                        var json = await streamReader.ReadToEndAsync();                        Console.WriteLine("Received event for TopicA.");                        Console.WriteLine($"Event Data: {json}');                    }                });                // Route to handle events published to TopicB                endpoints.MapPost("B", async context =>                {                    // Read the event form request body.                    using (var streamReader = new StreamReader(context.Request.Body))                    {                        var json = await streamReader.ReadToEndAsync();                        Console.WriteLine("Received event for TopicB.");                        Console.WriteLine($"Event Data: {json}");                    }                });            });        }    }}
复制代码


向订阅这些主题的服务发布事件非常简单,只需使用主题和有效负载的名称调用 Dapr 本地 http 发布 API 一样简单。下面的示例节点代码展示了如何使用 Dapr 发布 API(在本地端口 3500 上),这也可以使用 curl 命令来完成:


curl -X POST http://localhost:3500/vl.0/publish/A \ -H "Content-Type: application/json" \ -d '{"status": "completed"}'
复制代码


const express = require('express'’);const path = require('path');const request = require('request');const bodyParser = require('body-parser');const app = express();app.use(bodyParser.json());const port = 8080;const daprllrl = 'http://localhost:${process.env.DAPR_HTTP_PORT || 3500}/vl.0';app.post('/publish', (req, res) => {    console.log("Publishing: ", req.body);    const publishUrl = '${daprUrl}/publish/${req.body.messageType}';    request( { uri: publishUrl, method: ’POST', json: req.body } );    res.sendStatus(200);});app.listen(process.env.PORT || port, () => console.log('Listening on port ${port}!'));
复制代码


如这些示例代码所示,在服务中使用 Dapr 并不需要获取编译时依赖项,只需简单地使用消息体创建 URL 即可。

Sidecar 架构与支持的基础设施

Dapr 将它的 API 作为 Sidecar 架构予以公开,无论是作为容器还是作为进程,都不需要应用代码包含任何 Dapr 运行时代码。这使得与 Dapr 的集成从其它运行时变得很容易,并且提供了应用逻辑的分离,从而提高了可支持性。


Dapr 作为 Sidecar 进程运行。



在 Kubernetes 这样的容器托管环境中,Dapr 作为 Sidecar 容器运行,应用程序容器位于同一个 pod 中。


Dapr 作为 Sidecar 容器在 Kubernetes pod 中运行。



Dapr 有一个命令行界面,使入门变得轻松,并支持在开发人员机器、任何 Kubernetes 集群(包括 Minikube)以及其他基础设施平台(如 IoT Edge)和路线图上的 Service Fabric 上本地运行。要开始使用 Dapr,只需运行:


dapr init                                 (for local deployment)dapr init --kubernetes              (for Kubernetes deployment)
复制代码

开发语言 SDK 和框架

为了使 Dapr 在不同语言中的使用更加自然,它还包括了用于 Go、Java、JavaScript、.NET 和 Python 的特定语言 SDK。这些 SDK 通过类型化的语言 API 而不是调用 http/gRPC API 来公开 Dapr 构建块中的功能,例如保存状态、发布事件和创建角色。这使得开发人员能够用他们所选择的语言来编写无状态和有状态函数和角色的组合。因为这些 SDK 共享 Dapr 运行时,你甚至可以获得跨语言的角色和函数支持!


此外,Dapr 还可以与任何开发框架集成。例如,在 Dapr .NET SDK 中,你将发现 ASP.NET Core 集成,它带来了状态路由控制器,可以响应来自其他服务的 pib/sub 事件,使 ASP.NET Core 成为构建微服务 Web 应用的更好框架。


原文链接:


Announcing Dapr, an open source project to make it easier for every developer to build microservice applications


2019-10-17 11:4413241
用户头像

发布了 526 篇内容, 共 240.5 次阅读, 收获喜欢 1543 次。

关注

评论 4 条评论

发布
用户头像
dapr提供了一个以grpc为通信基础的"spring cloud",对于服务间的rpc调用,消息传播,服务状态都有了极大的跨语言支持,但为何不提供事件溯源呢?
2019-10-21 09:33
回复
用户头像
居然不是C#
2019-10-18 13:30
回复
用户头像
很看好dapr的前途
2019-10-17 12:45
回复
用户头像
现在中文网还没有多少Dapr的资料,InfoQ最快也最翔实,优秀!
2019-10-17 12:19
回复
没有更多了
发现更多内容

Vue-13-Vif和Vshow的区别

Python研究所

6月月更

【LeetCode】乘积小于 K 的子数组Java题解

Albert

LeetCode 6月月更

开源Star10K+数据库工具Beekeeper上手体验,免费够酷值得拥有!

MegaQi

数据库管理工具 6月月更 #开源项目体验

HashSet与WeakHashMap的理解

源字节1号

GNU/Linux知识库(1)- 历史和演变

冯亮

Linux DevOps GNU

力扣每日一练之数组上篇Day1

京与旧铺

6月月更

JavaScript基础语法知识遨游记

未见花闻

6月月更

BOM

Jason199

js BOM 6月月更

使用统计数据消除生活中的无谓

宇宙之一粟

贝叶斯公式 6月月更

uni-app进阶之模版语法与数据绑定【day7】

恒山其若陋兮

6月月更

学生管理系统的考试试卷存储方案

爱晒太阳的大白

【Python技能树共建】with...as... 实战

梦想橡皮擦

Python 6月月更

作为神经搜索生态的开创者,Jina AI 在做什么?

Jina AI

Python 深度学习 开源 云原生 搜索

成为架构师需要点亮哪些知识树

奔向架构师

数据仓库 架构师 6月月更

Docker 实用技巧三

Nick

Docker 容器 实用技巧 6月月更 实操

数据库每日一题---第16天:计算特殊奖金

知心宝贝

数据库 云计算 前端 后端 6月月更

leetcode 64. Minimum Path Sum 最小路径和(中等)

okokabcd

LeetCode 动态规划 数据结构与算法

InfoQ 极客传媒 15 周年庆征文|Vim 常用快捷键

耳东@Erdong

vim 运维 快捷键 6月月更 InfoQ极客传媒15周年庆

什么是 IPv6?IPv6有哪些优势?

wljslmz

ipv6 IP地址 网络技术 6月月更

统一返回结果

卢卡多多

返回值 6月月更

市场冷空气来袭,SeekTiger如何逆流而上?

鳄鱼视界

JVM调优简要思想及简单案例-对象的回收与保留

zarmnosaj

6月月更

微服务稳定性保障

阿泽🧸

微服务 6月月更

读书笔记之:如何有效阅读

甜甜的白桃

读书笔记 读书 笔记 6月月更

Java Core 「11」AQS-AbstractQueuedSynchronizer

Samson

学习笔记 Java core 6月月更

flutter系列之:按比例缩放的AspectRatio和FractionallySizedBox

程序那些事

flutter 程序那些事 6月月更

模拟红绿灯来看GetX的定向刷新

岛上码农

flutter ios 前端 安卓 6月月更

Java—JVM II

武师叔

6月月更

稳了github star突破9k即时通讯IM开源项目OpenIM版本发布-生产环境重点关注

Geek_1ef48b

【愚公系列】2022年06月 通用职责分配原则(六)-多态原则

愚公搬代码

6月月更

字节Pico走“小”路

科技新知

重磅!微软开源微服务构建软件Dapr_服务革新_Dapr 项目主管_InfoQ精选文章