写点什么

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

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

关注

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

完美!华为爆出Redis宝典,原来Redis性能可压榨到极致

热爱java的分享家

Java 面试 程序人生 编程语言 经验分享

首次公布Java10W字面经,Github访问量破百万

热爱java的分享家

Java 架构 面试 程序人生 经验分享

淘特 Flutter 流式场景的深度优化

阿里巴巴终端技术

flutter ios android 移动应用 客户端开发

这样准备面试定能轻松斩获offer!(内附精选java面试题与答案)

Geek_1df311

Java 程序员 架构 面试

参赛必读!! 签约计划第二季考核要求

InfoQ写作社区官方

签约计划第二季 热门活动

莫慌!阿里人用五个模块讲明白了SpringCloud,可下载

热爱java的分享家

Java 架构 面试 编程语言 经验分享

Python代码阅读(第64篇):角度与弧度互转

Felix

Python 编程 Code 阅读代码 Python初学者

掘金新大陆——最后一个十亿蓝海

ExoPlayer播放在线TS文件无声音问题分析

Changing Lin

11月日更

研发效能团队如何拥抱开源社区?一些前沿理念与朴素认知

Zilliz

AI 收藏夹 Vol.002

Zilliz

智能客服"下半场":数据、技术与服务

百度大脑

人工智能

InfoQ 写作平台优质创作者签约计划第二季,我们来了!

InfoQ写作社区官方

签约计划第二季 热门活动

百度ERNIE新突破!登顶中文医疗信息处理权威榜单CBLUE冠军

科技热闻

盲盒app源码开发盲盒小程序原生开发搭建

风行无疆

硬核!阿里自爆虐心万字面试手册,Github上获赞89.7K

热爱java的分享家

Java 架构 面试 编程语言 经验分享

直播带货软件原生开发直播带货小程序平台搭建

风行无疆

PingCode Wiki 协同编辑技术揭秘

PingCode研发中心

wiki PingCode

中科柏诚加入信创生态实验室,助力金融领域关键核心技术攻关

联营汇聚

联想智慧服务获金耳唛奖总冠军暨业务交流会在京举行

科技大数据

IMS究竟有什么用?

鸿天hente

Js 异步处理演进,Callback=>Promise=>Observer

CRMEB

限量!腾讯高工用4部分讲清楚了Spring全家桶+微服务

热爱java的分享家

Java 面试 程序人生 编程语言 经验分享

双非渣硕,在传统公司磨炼四年后成功拿到阿里offer!(附面经分享)

Geek_1df311

Java 程序员 架构 面试

从落地效果看,转转选择TDengine的三个理由

TDengine

tdengine 后端 时序数据库

汽车之家 x StarRocks:极速实时数据分析实践

StarRocks

大数据 数据分析 StarRocks OLAP数据库

单元测试再出发

FunTester

Java 单元测试 测试框架 spock Groovy

为什么工业巨头们偏爱自建5G私有专网!

鸿天hente

WorkPlus协同办公系统的优势有哪些?

BeeWorks

花了30天才肝出来,史上最全面Java设计模式总结,看完再也不会忘

Tom弹架构

Java 架构 设计模式

工具 | pg_recovery 设计原理与源码解读

RadonDB

数据库 postgresql 源码 RadonDB

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