写点什么

重磅!微软开源微服务构建软件 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:4413415
用户头像

发布了 536 篇内容, 共 275.4 次阅读, 收获喜欢 1561 次。

关注

评论 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
回复
没有更多了
发现更多内容

《学会写作》学习笔记之如何拟标题

JiangX

28天写作

不会开发的你也能管理好企业漏洞,开源免费工具:洞察(insight II)

BigYoung

安全 安全漏洞 28天写作 2月春节不断更

夕四今晚加班到2点30,而王二还不打算走《打工人的那些事》

谙忆

架构训练营大作业(一)

一期一会

产品训练营-作业3

简小一

极客大学·产品经理训练营·第二章作业(二)

二大爷

极客大学 产品训练营

硬核!八张图搞懂 Flink 端到端精准一次处理语义 Exactly-once(深入原理,建议收藏)

五分钟学大数据

大数据 flink

精美的淘客项目完全开源啦,确定不来围观吗

Silently9527

Vue mybatis springboot uniapp

翻译:《实用的Python编程》00_Setup

codists

Python

图解计算机结构与体系分类!!

冰河

编程 程序员 高并发 计算机结构 操作系统原理

区块链在数字版权领域的应用发展报告(2020)

CECBC

版权保护

架构师训练营第十周作业

zamkai

被接连封杀后,出海的“TikTok们”都打算如何做?

李忠良

28天写作

Java并发包源码学习系列:阻塞队列实现之SynchronousQueue源码解析

Java 编程

分页方式,看这一篇就够了。

大伟

分页

一文看完TCP/IP协议基础知识点

28天瞎写的第二百三十五天:客服得有多专业?

树上

28天写作

Spring - IOC

小马哥

Java 架构师 spring 5 七日更

架构训练营大作业(二)

一期一会

静默安装Oracle也没那么恐怖

MySQL从删库到跑路

oracle

【LeetCode】子集问题debug模式查看数据变化

Albert

算法 LeetCode 2月春节不断更

产品训练营第三次作业

Geek_79e983

管理笔记[4]:组织管理的目标就是实现1+1>2

L3C老司机

中国为什么加快推进数字人民币

CECBC

数字货币

看完字节大佬的算法刷题宝典,我直接手撕了500道算法算法题

程序员 面试 算法

京东支付SDK重构设计与实现

京东数科风险算法与技术

翻译:《实用的Python编程》README

codists

Python

「产品经理训练营」作业03:利益相关方识别

狷介

产品经理训练营

学习计算机视觉

IT蜗壳-Tango

OpenCV 计算机视觉 2月春节不断更

批判性思维自修课(六)

石君

28天写作 批判性思维

为啥写的mybatis插件没用?一场mybatis插件加载机制的探索之旅

altantisor

spring Boot Starter mybatis源码

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