使用Dapr和Java改进微服务DevOps

arthur Souza, Paul Yuknewicz
微软Azure首席软件工程经理,首席集团产品经理
微软Azure

某些DevOps实践成为分布式云原生开发的必备条件。

其他的对于高代码质量交付是至关重要的。

让我们来探索它们以及它们对项目成功的影响

视频记录

大家好,欢迎大家。感谢参加今天的会议,今天,Artur和我将讨论用一种叫做Dapr的新技术和Java一起改进微服务和DevOps过程。我是Paul Yuknewicz,我是Azure团队的产品主管之一。我的重点是Dev平台和框架,我也是一个dpr社区成员。

我是Artur Souza,我是Dapr团队的工程经理,也是Dapr的维护者。

好了,我和Artur在这个团队已经有一段时间了,在过去的几年里,我们一直在与许多开发者和运营商合作,我们一直在了解需求和最大的挑战。我们经常听到的一件事是,团队需要非常高效地构建、部署和自动化构建微服务的过程。我们经常听到,阻碍他们发展的是一组有限的工具和运行时间,无法使用微服务构建这些更加分布式的应用程序。即使存在运行时选择,我们也发现这些选择往往非常有限,要么是严格控制的功能集,要么是它们只支持一种特定的语言,而不是您在团队中碰巧使用的语言。

我们经常听到的另一个需求是,在我们的过程中,我们需要针对许多不同的平台和不同的环境。举个例子,现在一个更现代的目标是Kubernetes,很多工作负载都试图以Kubernetes为目标,但我们也有很多工作负载运行在云上的vm上,运行在边缘上,甚至混合在一起。因此,我们开始着手减轻在许多不同环境中运行的挑战,并确保更好的可移植性。

说到这里,下一个是Dapr。Dapr的字面意思是分布式应用程序运行时,这就是它的缩写,Dapr是关于更快地构建分布式应用程序的,这就是我们选择Dapr的原因。具体来说,Dapr是一组api,这些api真正关注的是构建可靠的微服务,并确保你的微服务非常可移植。仔细看一下这个,我们在Dapr中看到的东西,首先,就像我们提到的,我们有一组api, api是为最常见的场景准备的,无论是服务到服务调用,如果我们构建出这个图,我们会看到。

还有一种非常常见的应用程序类型是Pub/Sub,其中我们有异步消息和代理,以及一些关于将接收的内容的保证。我们在Dapr和Dapr运行时中拥有的一个总体特性是弹性。比如重试、弹性呼叫、熔断机制、退出和不同的策略。这是我们要持续投资的东西,所以当我们建立Dapr时,每一步都会有越来越多的弹性。

正如我在谈到异步时提到的,消息传递非常重要,因此无论是使用消息还是使用事件,都有许多内置的集成。正如我们在图中看到的那样,如果你最喜欢的恰好是Kafka或RabbitMQ,或者使用其中一个公共云,我们会支持很多这样的集成,而且它们会随着时间的推移而增长。正如我在挑战幻灯片中提到的,我们真的开始让Dapr便携。

所以Dapr本身是可移植的运行时你可以在很多不同的环境中运行它,你可以在你的机器上本地运行它,只用CLI,你可以在所有不同的环境中安装它从staging, pre-prod,一直到prod,你会有很多不同的环境差异。例如,你可以在不同的云环境中运行,你可以在多云环境中运行,你可以在Kubernetes中运行,你可以在没有Kubernetes的情况下运行,你可以在Edge上运行。

所以在任何地方运行Dapr,因此,能够在任何地方运行你的微服务,是一个非常重要的目标。不仅是应用程序和主机环境,还有你的倾向,对吧?我们讨论了事件代理之类的东西。我们想要确保免费的、开源的存储和状态管理服务,比如Pub/Sub代理和秘密存储,你选择的最喜欢的那些也能很好地与Dapr一起工作,你只要针对一组标准的api编写代码,我们就能通过配置动态地绑定到你选择的软件。

这里,当我们缩小时,我们可以看到它是如何工作的几个不同的层。我们的应用程序代码,我们用我们最喜欢的一种语言来写。今天我们真正关注的是Java和Spring作为我们的堆栈,然而,重要的是要看到我们今天使用和喜爱的许多通用语言,无论是Go还是Note或Python或。net,甚至是c++,作为本地语言,你可以用其中任何一种编写应用程序代码,你可以以restful的方式从Dapr调用api。正如我们在图中所示,您可以使用http或gRPC进行静态调用,因此我们支持两种最常见的API样式。你看到了我们在Dapr盒子中启用的一组场景,我们看到开发人员和运维人员开始时最常见的场景,是服务到服务的调用,在最左边。在中间,发布和订阅用于编写异步消息和基于事件的应用,这也很常见。

但随着你与微服务应用的发展和深化,你会增加可观察性,你会有秘密。如果你有成千上万个有状态的对象,你可以使用像actor这样的东西,API集非常广泛它会不断增长,就像我提到的,它是为了让你在做普通测试时更有效率。最后,如果我们继续讨论托管基础设施,我只想指出,Dapr可以在许多不同的主机上运行,比如Kubernetes,我认为这是一个值得考虑的重要主机,还有我们可以运行的所有或许多容器和PaaS服务,无论是在AWS、谷歌、Azure还是阿里云,你也可以在vm上运行,你可以在Edge上运行。实际上,Dapr会让你灵活地在不同地方运行相同的应用,相同的代码而不需要重新构建,这是Dapr的优势和优点之一。

接下来,我们将介绍实现这种可移植性的方法之一,即通过组件模型。如果你仔细想想,Dapr有一组API,我提到的是宁静的,它们是一致的,所以每一个这些东西,不管是国家商店,状态管理,或发布/订阅,这是一个API,但是我们也有一系列的组件,就像一对多的关系,你可以回八API与您最喜爱的组件,和让我们酒吧/订阅的案例中,它可能是在我的本地机器上,它可以是复述,并在生产中,可以是RabbitMQ,因为这是我的团队的选择。只需使用可切换的YAML文件,我就可以有效地配置环境并将mount绑定到我最喜欢的组件,而无需更改应用程序代码,因此这是我们实现应用程序端到端可移植性的方法之一。今天,我们有超过70个可用的组件,许多最流行的开源和云供应商都提供了组件,我们计划与社区合作,随着时间的推移不断发展。

现在,其中一个重要的技术基础,我知道Artur会花更多的时间向你们展示它的实际应用,就是侧斗模型。现在,通常当你听到sidecar时,我们会把Docker和Docker容器看作sidecar。我想要小心地指出,这里我们讨论的是过程。我的应用程序和二进制文件作为一个进程启动,假设我在JAR文件上运行Java,它作为一个进程启动,同时,Dapr sidecar也作为它自己的进程启动,它成为一个非常重要的进程,可以代表我们做事,就像大使一样。它可以调用,它可以使调用更可靠,它可以与我们拥有的不同组件一起工作,基本上为我们的应用程序提供了额外的弹性和可移植性层。作为一个开发人员,我只考虑做那个restful调用。如果我要调用Dapr进程,假设在我的开发机器上,默认情况下,它会在本地主机上,默认端口为3500。然后调用restful api。如果我想进行服务调用,我会调用invoke,然后调用我想要的服务和动作。

如果我想做一些状态管理,同样的事情,我调用相同的端点,但这次我将调用状态API。我将按项目67进行索引,这种方法一直在继续,所以对于发布/订阅,我可以这样做发布,我可以让另一个函数作为接收者和订阅者。你可以再次看到,sidecar进程位于app旁边它提供一致的API,它是非常可移植和可重新绑定到许多组件的东西。为了强调一下,你可以在容器中使用它,但容器实际上根本不是必需的,我认为这是Dapr的优点之一。也就是说,我给了你们一个概述。我想把话筒交给我的同事Artur他有很多实际操作的东西要展示。

好的,Paul,谢谢你对Dapr的精彩介绍。现在我们来看看在Java应用程序中使用Dapr的演示。我们将使用Twitter处理管道的例子,这个例子你也可以找到实现不同语言的例子。今天我们将再次展示它的Java版本。那么,让我们来看看其中的一些组件,这样你就能理解这个应用程序是如何工作的。

因此,我们有一个Twitter提供者应用程序,它通过Twitter绑定接收来自Dapr侧车的tweet,该绑定是一个已经在Dapr侧车中实现的组件,它通过每辆车接收tweet。您将通过向结算处理器发出服务请求来处理该信息,以获得结算分数,查看tweet是积极的,中性的还是消极的情绪,然后您将将tweet保存到状态存储并将其发布到Pub/Sub(使用Redis作为示例)。然后还有另一个组件叫tweet viewer它也有一个sidecar,它会渲染一个网站,它会订阅事件并使用web sockets在网站上显示它们。所以基本上就是这样,你订阅推文,获得情感评分,并在网站上显示它们。

我们来运行这个例子。所以你需要秘密,所以我们将在这个例子中使用,因为我们在本地运行,我们将使用一个[听不清00:12:47]文件,以及你可以从你的Twitter开发帐户中获得的所有属性,网站上有关于如何获取的说明。出于安全考虑,我们将把它们藏在这里。我们还将使用Azure认知服务API来对文本进行情感分析。

现在我们要运行第一个组件,也就是情绪处理器。在本例中,我们还模拟了应用程序的编译,在本例中我们使用Maven。如您所见,构建成功了,现在我们将执行Dapr运行来运行该流程。如你所见,我指定了组件的路径,应用程序将要监听的应用程序端口,并给出了ID,情感处理器,这非常重要。

Artur,如果我看一下,我习惯做Java/JAR传入我的JAR只是为了运行,看起来你在它前面加了一个Dapr run和服务名称之类的前缀。我是这么想的吗?

是的,这是一个很好的观察。因此,您仍然按照使用Java JAR的方式运行该进程,但是Dapr运行是有前缀的,因此它可以获得良好的Java环境变量,使DES2K能够开箱即用。

这很好。我想这也会启动挎斗,对吧?

是的,这一切都是从侧边车开始的。好问题。我将在下一个进程中再次运行Dapr,它遵循相同的策略,但是端口不同,正如您所看到的。组件路径可以共享,它不需要每次运行都是唯一的,正如你所看到的,你得到了一些tweet,看看那个。你也会得到情绪分析。

现在让我们运行实际的web UI我们可以看到这些tweet和情感分析一起显示,我们总是运行Dapr运行,同样,组件路径和应用程序端口这个sidecar端口是由Dapr运行随机决定的,所以我不需要担心sidecar端口的冲突。我们得到了显示,现在我们要在web浏览器上显示这个。正如你所看到的,这个图标,就像一张带有红色、蓝色或灰色的脸。好了,向你展示每条推文的情感,当然,它会收到不同语言的推文。这就是如何在本地使用Dapr运行应用程序。

让我们深入了解一下Java SDK是如何为Dapr工作的。如果你有一个Java应用,你可以在不同的层与Dapr集成,你可以使用基本SDK,它允许你做一些事情,比如状态存储,发布/订阅,保密,甚至某种程度上的绑定。现在,如果您想要使用角色,您现在可以依赖于另一个工件,它是一个Dapr。sdk actors,它也包括基本的sdk,通过这种方式,你也可以调用actor,或者你也可以通过内置actor运行时来服务actor。

如果您想将Dapr与Spring Boot一起使用,您甚至可以通过直接依赖Dapr SDK Spring Boot构件来获得更多的便利,在那里您将自动拥有Dapr所需的控制器。例如,您可以通过主题注释处理Pub/Sub订阅,或者您可以让actor运行时句柄也自动为您实现Spring Boot。如果你想使用Spring Boot,这是一个平滑的集成,如果你不使用Spring Boot,你只需要依赖其他版本,但它可能需要手动实现每个控制器。但同样,我们可以在未来添加更多,但现在我们真正关注的是Spring Boot应用程序。所以你依赖这些构件的方式和你依赖其他Maven依赖的方式是一样的,无论是在Maven中还是通过Gradle,都是一样的。SDK的最新版本是131。

那么你如何使用,例如,我们在这个例子中看到的状态存储。所以你Dapr客户机,在某种意义上,可以重用,你调用保存状态,通过状态存储名称,您传递的关键,在这种情况下它是行星,你传递的对象,在本例中是一个复杂的类型称为行星,就是自动序列化的SDK追逐,和国家商店,你会得到一个关键应用程序的想法作为前缀和关键项目的后缀,然后你可以作为一个序列化对象的价值。这适用于多个状态存储,您决定使用配置,您的代码不会更改。

而get则相反,你做一个。get状态然后你做同样的事情,传递状态存储名,键,然后传递你正在读取的类类型这样SDK就知道如何反序列化它回给你请求的对象,这和Java中任何序列化API的模式是一样的。我想把这个调用出来,我们正在使用Project Reactor,这就是为什么你会在这个例子中看到。block使这个调用同步。如果你想通过productreactor使用异步API,它已经内置在API中,不需要给它做任何适配器。

而Dapr客户端,你只使用构建器,这里你根本不需要传递任何参数,只有当你做任何不同的事情时,你可能需要指定一个不同的端口,但如果你使用Dapr采用的标准方式,你只调用构建器。建立和你就可以开始了。构建器将知道sidecar正在运行的端口是什么,因为Dapr运行会注入构建器知道如何解析的环境变量。

现在我们来看看Pub/Sub模式。在这种情况下,我们将发布一个事件和save state非常类似,pub up名称是组件名称,在这种情况下,是主题名称,我们将发布哪个主题[听不清00:20:22]哪个对象将被序列化成JSON。然后在订阅者端,我们将在这里使用Spring Boot示例,其中我们有add topic注释,这是一个Dapr注释,它将告诉端点路径应该通过我作为Pub/Sub名称传递的Pub/Sub接收来自订单主题的事件。为了获得事件,我还接收了作为云事件的事件。因此,Dapr使用云事件抽象,因此您可以为云事件添加注释和额外属性,包括跟踪。这就是为什么我们得到跟踪,即使是Pub/Sub,因为我们使用了云事件抽象。

这很酷,云事件,得到那个标准接口。如果我想得到,比如说,原始的潜在事件,我也可以这样做吗?

是的,如果你想获得原始事件,你可以。在本例中,您得到event。数据并立即获得事件。

听起来不错。因为我认为我们会遇到很多问题,比如,“嘿,Dapr是否隐藏了太多的对象模型?”假设。

是的,如果你愿意,还有另一种方法来处理这个问题,假设你在Redis中订阅一个主题,发布者不使用Dapr,也不使用云事件抽象。在这种情况下,您可以将订阅配置为订阅原始事件,然后双侧车将自动将其包装为应该与Dapr订阅兼容的云事件。所以你甚至可以订阅事件,从没有使用Dapr的发布者那里。所以这又回到了最初介绍的,你说你可以逐步采用,所以你不需要整个公司都采用Dapr。例如,对于发布/订阅,您可以说,“好的,我将使用Dapr订阅,即使我的发布者(它正在审核)不使用Dapr。

太棒了。在这个过程中,这听起来好像使我的API更加标准。

是的,是的,现在我们可以开始服务调用了。服务调用,有两种方法。一种方法是,你可以使用SDK中的调用服务API,这是用于HTTP的,然后你可以传递应用ID, checkout或路径,完整路径,你传递的更新和你使用的HTTP功能。现在您可能会说,“那么使用它比使用标准http调用有什么优势呢?”我想说的是,优点是您的应用程序不必在端点为服务进行配置。如你所见,我不知道card服务是什么主机,我不需要知道,Dapr的服务发现特性会为我处理这个。

如果你想在没有SDK的情况下使用,你可以说,哦,我已经在做了,它们应该被正确地调用到我的服务,为什么我要选择Java SDK,只是为了进行http调用这是一个很好的论点,出于这个原因,我们也为http调用和JRPC创建了一个代理解决方案,在这个解决方案中,除了在端点中添加一个额外的标头外,不需要更改进行服务调用的现有代码。你以同样的方式传递端点,你传递到你的服务,但是你在Dapr运行时的端口中调用本地主机。在这个例子中,我们将使用标准的3500,但它可以是可配置的,你也可以从环境变量中获得这个,如果你愿意,然后你传递header, Dapr app ID。

[听不清00:24:24]所以接下来要做的是,这部分会像http代理一样,Dapr会接收请求,你会明白,“哦,这个请求实际上不是针对sidecar的。”这个实际的请求现在必须通过ID卡类型转发到另一个应用程序。它会进行翻译,代表你进行HB调用,然后把响应转发给你。因此,您只需要在代码中做很小的更改就可以使用Dapr进行服务调用,甚至不需要使用SDK。

再补充一点,我们看到,我认为,许多开发者开始使用这种方法因为他们有http,他们有gRPC和原型代码,所以他们可以通过添加头开始使用Dapr,就像你展示的那样,这是一个非常好的方法,对吧?然后,如果我想为全新的代码编写简洁的代码,我有另一种SDK方法。所以你有很好的选择。

是的,这是正确的。如果我们继续,我们如何做我们用Kubernetes做的相同的事情呢?我是否需要重写我的应用程序,使用Kubernetes?答案是否定的。您的应用程序使用相同的代码,相同的位。你可以在本地运行,也可以运行Kubernetes,我们将展示如何运行。同样的例子,但都在Kubernetes上。好了,我们去拿吊舱吧。所以Dapr安装在Dapr系统的命名空间里,就像你看到的仪表盘,操作符,位置,避难所和sidecar。我们还在默认名称空间中安装了Redis,然后我们还有组件,绑定,加压器和Pub/Sub组件。 So if you can look at the binding, we’re going to see that we use the secret reference here. So again, no hardcoded secrets, it’s all part of the Kubernetes secret store.

如果你看处理器,抱歉,我在这里写错了,你可以看到我们也使用了一个秘密存储。抱歉,在这种情况下,它只是部署。抱歉,这是部署。现在我们有了提供者的部署你可以注意到它们都有注释,Dapr注释。这将告诉Dapr sidecar注入器你需要注入一个sidecar,所以没有部署你必须声明Dapr sidecar,在你添加注释后自动注入,[听不清00:27:18]组件也使用Redis。

现在我们来看一下查看器部署,同样的注释用于Dapr,我需要调用app ID也被指定。在这个例子中,我们也有一个服务,所以我们可以有一个入口。好的,我们将简单地应用所有这些ml,如果你看一下这些pod,我们现在已经创建了pod。现在看起来它有两个容器,看到了吗?尽管我们只需要为应用找到一个,但现在它有了两个因为sidecar注入器检测到了注释并说,好,让我把dapr sidecar注入这个位置现在他们都跑了。

现在让我们看一下日志。让我们从处理器开始。哦,我忘了写名字了。好的,解析器已经启动。哦,我想我需要复制SOL,整个提供者URL,稍等,我来修正一下,klogs,提供者。哇,好吧,我们收到一条推特。我能看出来,有些是葡萄牙语的。

让真正的Twitter进入演示总是令人兴奋的。

是的。好了,现在我们要为查看器获取端点。我们在这个例子中使用minikube,所以让我们使用minikube IP。

但这可以在任何Kubernetes上运行,对吧?

是的,它也可以在任何具有公共IP的Kubernetes上运行。然后我们也开始收到推文。这就是Kubernetes上的演示。

让我们深入了解每个组件,了解代码的样子。这里我们看到Twitter的绑定组件。所以这些秘密都不是硬编码的。我们在这里使用秘密引用,它直接到Kubernetes。如果你运行本地主机,你将从本地文件获取。所以你不需要担心,“哦,秘密是从哪里来的。”这是另一种构型。你也有消息buzz组件,我们在这个例子中使用Redis,我们只是在本地主机上使用空密码,但如果你想在生产中这样做,你可以把这个YAML替换为一个秘密,你的代码没有变化。状态存储也是一样,我们有Redis使用本地主机,如果我们在秘密存储中,你可以有秘密存储,在这个例子中,在邻近文件中从本地主机定义它。所以当你在本地运行时,你不一定需要使用Redis secret store,当然,你会使用这个文件。

当你得到一个tweet,记得你收到绑定微博,我只是通过tweet对象,由弹簧自动反序列化为我,当我做Dapr客户取消服务,我将撤销情绪的情绪处理器路径,通过twitter对象,使用post和接收回情绪对象,然后我做一些反应堆通过这里,然后我翻译和响应,拯救国家,使用国家商店,通过tweet ID和分析推特,之后我发布了事件消息总线。

我想你能在这里看到,你有一个很有趣的工作流,但代码看起来就像你想要的工作流而不是你需要通过http,你的gRPC,来做连接的更多机器,这很酷。

是的,是的,所以我们在这里使用,来自反应器的特性,Dapr侧车被注入。我可以看到,我现在要展示我是怎么做的。这里有一个Dapr配置,我有一个构建器我通过autowire发送一个客户端?

对于应用程序,如果是Spring Boot应用程序,所有的区别在于您需要为Dapr的io添加包路径。对于Spring Boot, dapr会自动加载dapr工作所需的所有控制器,并接收所有回调调用,并为您处理主题注释。因此,只要添加扫描包列表,所有这些好处就会发生。

现在让我们看看情绪处理器。还是那个秘密仓库。在本例中,我们从控制器获得端点和订阅键,然后进行HP调用。我们通过http接收到它所说的情感,然后我们将HP调用到Azure认知服务。然后我们得到响应,我们把情感对象返回给用户。如果你看一下这段代码,实际上这里没有什么是Dapr特有的。

这是一种你可以看到服务职业是如何用Dapr工作的方式。您不需要重写接收端,所以它仍然是这样工作的,但是在这种情况下,我们使用的是Dapr的秘密特性。记住,你需要端点secret和订阅密钥secret,所有这些都来自Dapr get secret API。因此,您不需要在环境变量中硬编码任何秘密。你让Dapr帮你拿到了秘密。这就是这个应用程序如何采用Dapr,用于秘密存储。

从运维的角度问个小问题,我们展示的是开发者本地机器,但如果我有更多的环境,比如我在CI/CD管道中,我有分段,预生产,一直到生产,这会是什么样子?

对你来说,不同之处在于秘密存储文件将是不同的,或者如果你要去Kubernetes,你将把秘密用不同的值放在Kubernetes上。这样,应用程序可以在不同的配置下工作,而无需更改代码。因此,所有秘密存储组件都需要更改。

如果我使用Vault或Key Vault之类的东西,我也可以使用它们吗?

是的,你也可以使用Vault。我使用Vault而不是Kubernetes的秘密。你也可以这样做。所有这些都是在组件的YAML中处理的。好问题。

现在我们来看看推特查看器,推特查看器使用订阅功能,它有一个主题。我们有特殊的符号它是Spring Boot的Dapr SDK的一部分,你需要订阅推文,接收消息名,Pub/Sub名,到他的消息总线,和你在左边的YAML中看到的是一样的。在这个例子中,它将来自Redis或本地主机,但它也可以来自其他来源。如果您想在不同的环境中运行,替换组件YAML的相同策略也适用于此。

我们也有一个web套接字,但我保持抽象,因为它不是Dapr特定的逻辑,我们也接收…在这个例子中,我们有一种不同的方式来处理云事件。我们以字节的形式接收云事件,然后在代码中反序列化,这也是另一种方法。我们可以直接接收,已经解析过的,或者你可以调用我们提供的云事件对象的附加反序列化方法,抱歉,是我们在Dapr SDK中提供的云事件类。这些天,同样重要的是要指出,我们使用的是SLF4J,而不是Log4j,所以在这个时代,这只是一个很好的例子。

现在让我们使用RabbitMQ。所以如果你喜欢使用RabbitMQ,你只需要改变你的YAML就可以了。比如说,在本地主机上,你使用Redis,在测试环境中,使用RabbitMQ,没有问题。您只需针对不同的环境使用不同的YAML,这再次使DevOps的工作变得更加轻松,因为您不需要让开发人员在本地完全模仿您的环境。

听起来,sidecar做了很多繁重的工作,就像你提到的不同的框架和东西,所以即使有些东西需要修补,有些东西需要更新,听起来像Dapr团队会照顾它,并不断更新sidecar。

这也是另一个很好的例子。RabbitMQ组件正在不断发展,所以在Dapr sidecar的下一个版本中,已经有了对Dapr中RabbitMQ组件的修复。这些都是免费的,所以你不需要担心是否需要更新依赖?我是[听不清00:37:51]最新的吗?准备好用于生产了吗?所有这些都是由Dapr处理的,实际上你可以看到哪些组件对于生产使用来说是稳定的,哪些还不是,我们正在努力将越来越多的组件演变成稳定版本。另一件事是,当您使用sidecar模式时,您不必管理应用程序中的依赖冲突。假设你引入了一个第三方库连接,RabbitMQ,并且使用了一个冲突版本的依赖项。假设你的JSON序列化器是那个的冲突版本。您不再需要担心依赖冲突,因为所有这些都被隔离在一个单独的进程中。

好,我们来看看Zipkin。所以我们打开了URL, localhost9411,我们要去查询查看Dapr的事件。如果你看提供商,你可以看到推文事件发生需要多少时间。在这种情况下,你可以看看情绪分析,花了多长时间。如果你做一个节目,你可以看到它花了大约1.5秒,大部分时间是关于情绪处理器的调用。

如果你回去,我们也可以看一下发布事件,你可以在这里看到提供者如何,一旦有效负载在情感分析之后已经序列化,发布事件花费了大约1.3到1.4毫秒。之后,正如你所看到的,有一个小延迟,观众在1.6毫秒内接收到并处理它,所有这些都是由Dapr sidecar自动完成的。

如果你想在这些事件上有一个很好的上下文,你当然可以,用开放遥测SDK来装备你的应用,然后那将把所有这些跟踪事件包装在一个父跨度中,那个上下文必须来自一个应用。Dapr会为你添加那些事件作为子事件,在这个例子中,Dapr会自动为你处理,对于Pub/Sub,订阅者事件是发布者事件的子事件。

如果你想开始使用Dapr,看看我们的文档。您可以看到快速入门、入门指南、故障排除以及如何选择组件的示例。看看我们的GitHub页面,你可以通过查看你的问题开始,或者我们也想在那里做一个好的第一个问题。如果你是Java开发人员,看看我们的Java SDK[听不清00:41:00],有很多机会为SDK做出贡献。你甚至可以进化成一个维护者,如果你想承担责任,你也可以在看aka的时候看看这个例子。我们的社区在Discord上非常活跃,所以请查看我们的Discord频道,我们也有一个社区存储库,您可以在其中找到社区调用url和时间表。所以你也可以自由加入我们的社区电话,这通常是一个很好的地方,你也可以得到一个维护者的现场问题回答,当然,我们的推特账户,推特账户,dpardev。保罗,你还有什么要补充的吗?

不,我喜欢你的观点。我认为社区是Dapr最大的资产之一,我认为社区是Dapr最大的功能之一,所以我很高兴加入你们,记住很多Dapr实际上也是由社区构建的,所以到目前为止这是一件非常棒的事情。

是的,很多组件实际上来自社区,或者来自社区对合法和错误的需求,而且,社区在报告错误方面做得很好,所以对我们来说,让事情变得稳定是一条非常关键的道路,他们实际上报告了错误,社区在这方面也做得很出色。

哦,这也提醒了我,我认为事情进展顺利,社区发展的一个证明是,我们刚刚加入CNCF作为一个孵化器,所以这是非常令人兴奋的,希望我们之后会有更多的社区加入我们。

是的,这是真的。Dapr团队和社区都取得了巨大的成就。

是的。

好的,谢谢大家,还有……

谢谢你!

希望能再见到你。

要么释放,要么死亡