佛山市南海区水利投资建设有限公司网站,行业信息采集软件,基本信息型营销网站有哪些,宽带专家网站Dapr 和 Spring Cloud 的区别很多人都是使用 Spring Boot 和 Spring Cloud 来开发微服务。Dapr 也是开发微服务的框架#xff0c;它和 Spring Cloud 有什么区别呢#xff0c;其实这不是一个区别的问题#xff0c;它是不同的时代需要不同的框架。Spring Cloud 是一种产品它和 Spring Cloud 有什么区别呢其实这不是一个区别的问题它是不同的时代需要不同的框架。Spring Cloud 是一种产品提供了分布式应用程序所需的所有要素包括服务发现、消息传递/流处理、分布式跟踪、 以易于处理的形式从 SpringBoot 提供功能 到目前为止可能没有其他产品比 Spring Cloud 更易于使用。Spring Cloud 并没有重复制造轮子它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。Spring Cloud 是分布式应用程序开发中的重要产品足以影响语言选择。假如你想使用 Java 以外的语言开发微服务比如 golang你想用 Spring Cloud Spring Boot最终还是选择了使用 Java。Dapr 的出现是分布式应用程序开发中拥有了语言无关的微服务开发Dapr 足以替代 Spring Cloud 成为云原生分布式应用开发的选择。熟悉 Azure 的人可能会觉得它其实更像是 Service Fabric 的加强版。我们将 Spring Cloud 提供的组件与 Dapr 的构建块作一些横向对比总的来说无论是 Dapr 还是 Spring Cloud 上述这些项目都是想帮助开发人员简单快速地构建分布式应用。但是由于时代背景的原因它们的出发点、实现形式又存在一些差异。我们从分布式应用程序的三大支柱性功能来比较一下 Dapr 和 Spring Cloud服务调用传递异步消息分布式追踪1. 服务调用首先比较从应用程序调用另一个应用程序的功能。Dapr 的调用使用InvokeAPI源代码如下所示Value(${baseUrl})private String baseUrl;GetMapping(/invokeHello)public MapString, ? invokeHello() {Map?, ? result restTemplate.getForObject(baseUrl /hello, Map.class);return Map.of(baseUrl, baseUrl, remoteMessage, result);}baseUrl 可以通过为 Dapr 指定调用 API 的值来通过 Dapr 调用目标应用程序。http://localhost:${DAPR_HTTP_PORT}/v1.0/invoke/hello-app/methodDapr 在本地环境中使用 mDNS多播DNS从应用程序名称中查找目标服务运行的主机而 k8s 使用 k8s 本身的名称解析功能CoreDNS。在两者都不可用的环境中您当前必须使用 Consul。除此之外Dapr 的优势在于它基本上可以做到开箱即用。Spring Cloud 服务发现Spring Cloud 使用 Netflix Eureka 进行名称解析它具有 Eureka 服务器等效于上述内容作为名称解析的服务器每个应用程序都使用 Netflix 客户端向 Eureka 服务器注册自己并用它来构建客户端来解决自己的主机。服务注册表非常有用因为它允许客户端负载平衡并将服务提供商与使用者隔离开来而无需 DNS。服务器端 Eureka 服务器代码如下所示EnableEurekaServerSpringBootApplicationpublic class ServiceRegistrationAndDiscoveryServiceApplication {public static void main(String[] args) {SpringApplication.run(ServiceRegistrationAndDiscoveryServiceApplication.class, args);}}只需启动具有注释 EnableEurekaServer 的应用程序。当然您可以添加配置文件以进行精细设置或组合群集。Netflix 客户端源代码如下所示Value(${baseUrl})private String baseUrl;GetMapping(/invokeHello)public MapString, ? invokeHello() {Map?, ? result restTemplate.getForObject(baseUrl /hello, Map.class);return Map.of(baseUrl, baseUrl, remoteMessage, result);}与 Dapr 端的源代码相同。baseUrl 只要指定了应用程序名称 RestTemplate 就会使用 Eureka 发现客户端自动访问该应用程序。简单地说它比使用 Dapr 更容易理解。异构服务通信传统分布式中间件往往锁定某个语言比如 Java 体系通常会使用 Feign 或者 Dubbo 实现但它们并没有提供其他语言的库。因此如果是多语言的环境那么就需要基于某种通用协议如 REST 或者 GRPC 进行通信可能还会需要额外的注册中心和负载均衡器。当然现实中的情况往往要比这复杂的多并且考虑到会引入额外的中间件带来的运维方面的成本也需要慎重考虑。Dapr 提供了多语言的 SDK如 .NET、Java、Go、Rust、Python、PHP 等可以 使用 HTTP 或者 GRPC 的方式进行异构服务间的调用能很好地解决这个问题。Dapr 和 Spring Cloud 的服务调用哪个更好虽然 Dapr 不需要单独的 DNS但它更易于使用但 Spring Cloud 需要在本地环境中建立Eureka 服务器。当然它不是那么难建立所以不能说这是一个缺点。此外调用时的 URL 在 Spring Cloud 中更易于理解而 Dapr 的调用 API 会很长。当然这不是一个很大的缺点。Dapr 和 Spring Cloud 各有千秋但是在 Kubernetes 环境下Dapr 直接就利用了Kubernetes 的 Service 更加贴合云原生环境异构服务通信的支持更好。2.传递异步消息Dapr 的 Pus/sub APIDapr 使用消息传递的 Pub/sub API 发送消息只需创建订阅配置文件和 Web API 即可接收消息采用标准的 CloudEvents 格式。发送消息的源代码如下所示Value(${pubsubUrl})private String pubsubUrl;PostMapping(/publish)public void publish(RequestBody MyMessage message) {restTemplate.postForObject(pubsubUrl, message, Void.class);}您可以通过指定名为 pubsubUrl 的大写 Pub/sub API 向消息代理发送消息。http://localhost:${DAPR_HTTP_PORT}/v1.0/publish/rabbitmq-pubsub/my-message然后是接收消息的源代码。它看起来像这样PostMapping(/subscribe)public void subscribe(RequestBody CloudEventMyMessage cloudEventMessage) {System.out.println(subscriber is called);System.out.println(message);}只需创建一个 Web API 来接收消息。若要利用此 Web API请创建类似于以下内容的配置文件apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:name: subscription
spec:pubsubname: rabbitmq-pubsubtopic: my-messageroute: /subscribe
scopes:
- subscribe-appmetadata.name 值不是特别可用因此您可以为其指定任何名称。pubsubname 是 pubsub 的名称。使用默认情况下设置的 pubsub。topic 是消息主题。此处指定了发布端应用程序中指定的 my-message。route 是要调用的 Web 应用程序的路径。因为它正在等待的路径SubscribeController/subscribescopes 是正在等待的应用程序的应用 id。这一次我将启动一个应用程序应用程序的应用程序称为子脚本端的应用程序所以我指定它 subscribe-app。如果在此处列出多个应用程序的 app-id则多个应用程序可以接收相同的消息。GitHub 示例代码将此文件放在中。如果要使用它请将其复制到用户指令。subscribe/.dapr/components/subscription.yamlSpring Cloud Stream使用 spring cloud stream 向 cloud 发布信。在 spring cloud stream 2.x 到 3.x 之间API 发生了重大变化现在更特定于流处理。在这里我将介绍 3.x 版本。发送消息一方的源代码PostMapping(/publish)public void publish(RequestBody MyMessage message) {streamBridge.send(my-message-0, message);}使用类StreamBridge发送消息。此外在配置文件中写入要发送到源代码中指定消息的键的消息代理。spring.cloud.stream.bindings.my-message-0.destinationmy-message此处指定的值用作 RabbitMQ 交换的名称。然后是接收消息的源代码。Beanpublic ConsumerMyMessage subscribe() {return (map) - {System.out.println(subscriber is called);System.out.println(map);};}使用包 java.util.funciton 的 Consumer 和 Function 来实现 而不是像 Dapr 这样的标准的 Web API。然后创建一个配置文件以便在收到消息时调用此方法 Bean。spring.cloud.stream.bindings.subscribe-in-0.destinationmy-messagespring.cloud.stream.bindings.subscribe-in-0.groupmy-message-subscribe上面的值用作 Exchange 的名称下面的值用作队列的名称。设置中有一些问题就是很难理解。然而有一种令人信服的感觉是将子脚本端视为 “函数” 而不是 “API” 并实现它。您可能从未阅读过此版本的 Spring Cloud Stream 的源代码因此您可能已经将多个调用合并到 WebFlux 的非阻塞中而不是逐个从消息代理接收和处理消息。这有性能优势。Dapr 提供了一些基础服务的抽象接口以消息中间件为例Dapr 支持以下中间件的 Pub/Sub用 Dapr 抽象接口来使用基础服务能力的好处是———当你需要更换中间件的时候可以少动点代码换句话也可以说是增加了服务的可移植性在熬小剑的文章里也有相关描述。Dapr 使用 HTTP 进行消息传递内部的通信通过 GRPC 进行传递但 Spring Cloud Stream 使用自己的类进行消息传递。因此虽然 Dapr 在测试时更容易替换为另一个进程并使用 curl 命令进行测试。Dapr 在可操作性方面会更好。3.分布式追踪Dapr 的分布式追踪支持在 Dapr 中只需编写配置文件即可启用分布式追踪。配置文件有以下内容。apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:name: daprConfig
spec:tracing:samplingRate: 1zipkin:endpointAddress: http://localhost:9411/api/v2/spans只需指定分布式跟踪的采样率和 Zipkin 服务器的地址即可启用分布式追踪。但是您必须自己传播跟踪 ID因此您需要编写如下代码GetMapping(/invokeHello)public MapString, ? invokeHello(RequestHeader(traceparent) String traceparent) {HttpHeaders httpHeaders new HttpHeaders();httpHeaders.set(traceparent, traceparent);HttpEntity? request new HttpEntity(httpHeaders);Map?, ? result restTemplate.exchange(helloUrl /hello, HttpMethod.GET, request, Map.class).getBody();return Map.of(baseUrl, helloUrl, remoteMessage, result);}在 HTTP 标头中接收到的标头值 traceparent 将传递给下一个请求的 HTTP 标头。Spring Cloud Sleuth使用 Spring Cloud Sleuth 在 Spring Cloud 中进行分布式追踪。将 Spring Cloud Sleuth 添加到依赖项并创建配置文件如下所示spring.sleuth.sampler.rate100spring.zipkin.sender.typewebspring.zipkin.baseUrlhttp://localhost:9411使用此设置将启用分布式追踪并将追踪信息发送到 Zipkin。分布式追踪涵盖了从与 RestTemplate 和 WebClient 的 HTTP 通信、与 Spring Cloud Stream 的消息传递等所有内容并且还自动传播 Dapr 存在问题的跟踪 ID。分布式追踪上 Dapr 不需要修改应用通过配置就可以轻松的调整。综合比较到目前为止我们已经比较了 Dapr 和 Spring Cloud 的三个功能但总的来说哪个更好Dapr 在清晰性和通过 HTTP 的松耦合方面具有优势另外不仅考虑到这三个功能还考虑到其他功能或者世界信息量的差异可以说 Dapr 更胜一筹。与版本升级相关的痛苦那么我为什么不选择 Spring Cloud 而选择 Dapr 呢有个重要因素是 “版本兼容性和版本升级问题” 。例如如果您的系统运行旧版本的 Java 和 Spring Boot并且您尝试在新系统上使用更新版本的 Java 和 Spring Boot 进行开发如果您尝试在每个系统上使用 Spring Cloud每个 Spring Boot 由于对应的 Spring Cloud 版本不同有时会失去兼容性。比如随着 Spring Cloud 的版本升级内部使用的 Eureka 版本升级时协议发生了变化如前所述Spring Cloud Stream 是 2.x 中 了API 终端。如果是这样最好继续更新 Java 、 Spring Boot 和 Spring Cloud 到最新版本。但是Spring Cloud 往往是有与版本升级相关的大型工作。这是因为 Cloud Native 这个领域对应的产品和趋势都发生了变化Spring Cloud 试图跟风的时候不得不失去兼容性。另外作为一个稍微小一点的问题如果由于Spring Boot 的提供速度和 Spring Cloud 的提供速度不同以及依赖的复杂度等原因尝试升级 Spring Boot 的版本Spring Cloud 还不支持有时候引用库的版本不一样会报错。通过体验这方面的痛苦而不是 Spring Cloud 不好“与提供 Web API 的应用程序和支持它的基础设施接壤的层更加松散耦合并且每个版本都是独立的。最好能够上传吧。”这就是它被用于 Dapr 而不是 Spring Cloud 的原因。总结在服务调用方面Dapr 和 Spring Cloud 变化不大。在消息传递方面Dapr 更简单并具有更好的性能。对于分布式跟踪Spring Cloud 比 Dapr 更复杂、更易于使用。Spring Cloud 版本升级让你吃不少苦头有点难以理解 Spring Cloud 文档在哪里以及是什么随着具有各种功能的历史产品变得更加复杂文档可能会变得更加复杂。当然Spring 的好处是有许多指南、博客、Demo 材料等作为该领域的补充。Spring Cloud 这样的微服务框架把微服务架构上的很多东西也带到了代码开发上来。虽然 Spring Cloud 做了封装和简化但开发的时候你还是会分心去处理它不能完全只关注业务。 Dapr 是微服务的发展方向它简化微服务的开发把微服务架构方面的东西都剥离出来成为基础设施开发只需关注具体的业务实现。所以 Mecha 架构的 Dapr 完全可以取代 Spring Cloud。而且具备更多优势更加云原生和 Kubernetes 结合更好。业务代码无需集成 SDK这样决定了 SDK 升级会更加方便降低了耦合。Dapr 通过把一些构建微服务应用所需的最佳实践内置到开放、独立的 Building Block 中Dapr 还在 Actor 运行时中提供了许多功能包括并发控制状态管理生命周期管理如 Actor 的激活/停用以及用于唤醒 Actor 的 Timer(计时器) 和Reminder(提醒)。Dapr 让开发人员更加专注于业务逻辑代码的编写即可开发出功能强大的微服务应用。更为重要的是Dapr 还抽象了运行环境避免微服务应用和运行环境强绑定这也是很多团队“假上云” —— 仅使用VM的原因之一。并且支撑 Dapr 的运行环境不仅仅限于 Cloud还有广阔的 Edge。参考文章https://xie.infoq.cn/article/aa422c431873fc7b1de3591e1https://xie.infoq.cn/article/047e1ece428ef11350f7a129chttps://www.infoq.cn/article/ex3rr5jCByXOCX7mwJbuhttps://xie.infoq.cn/article/7308df260ebbf5995a1401115https://github.com/dapr/dapr/blob/master/docs/decision_records/sdk/SDK-002-java-jdk-versions.md通过 K8s 自带技能卸下 SpringCloud 依赖