分布式服务调用RPC框架复习

目录

1、Dubbo概念与架构

1.1 Dubbo简介

1.2 注册与发现流程图

1.3 Dubbo架构图

2、Dubbo调用流程

3、关于Dubbo 服务治理

3.1 Dubbo通信协议

3.2 序列化方式

3.3 负载均衡算法

4、Dubbo与Spring Cloud关系

4.1 相似之处

4.2 差异之处

5、Dubbo 与 gRPC 关系

6、其他常见零散面试问题

6.1 Dubbo 的容错策略有哪些?如何选择?

6.2 注册中心宕机,服务间是否可以继续通信?

6.3 Dubbo启动时如果依赖的服务不可用会怎样?

6.4 Dubbo 如何优雅停机?

6.4 Dubbo 用到哪些设计模式


1、Dubbo概念与架构

1.1 Dubbo简介

微服务的分布式特性使得应用间的依赖、网络交互、数据传输变得更频繁,因此不同的应用需要定义、暴露或调用 RPC 服务,那么这些 RPC 服务如何定义、如何与应用开发框架结合、服务调用行为如何控制?这就是 Dubbo 服务开发框架的含义,Dubbo 在微服务应用开发框架之上抽象了一套 RPC 服务定义、暴露、调用与治理的编程范式,比如 Dubbo Java 作为服务开发框架,当运行在 Spring 体系时就是构建在 Spring Boot 应用开发框架之上的微服务开发框架,并在此之上抽象了一套 RPC 服务定义、暴露、调用与治理的编程范式。

Dubbo 作为服务开发框架包含的具体内容如下:

  • RPC 服务定义、开发范式:比如 Dubbo 支持通过 IDL 定义服务,也支持编程语言特有的服务开发定义方式,如通过 Java Interface 定义服务。
  • RPC 服务发布与调用 API:Dubbo 支持同步、异步、Reactive Streaming 等服务调用编程模式,还支持请求上下文 API、设置超时时间等。
  • 服务治理策略、流程与适配方式等:作为服务框架数据面,Dubbo 定义了服务地址发现、负载均衡策略、基于规则的流量路由、Metrics 指标采集等服务治理抽象,并适配到特定的产品实现。

1.2 注册与发现流程图

Dubbo主要提供了3大核心功能:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

1.3 Dubbo架构图

Dubbo三大组件:

  • 注册中心:协调 Consumer 与 Provider 之间的地址注册与发现
  • 配置中心:
    • 存储 Dubbo 启动阶段的全局配置,保证配置的跨环境共享与全局一致性 。
    • 负责服务治理规则(路由规则、动态配置等)的存储与推送。
  • 元数据中心:
    • 接收 Provider 上报的服务接口元数据,为 Admin 等控制台提供运维能力(如服务测试、接口文档等) 。
    • 作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展

以下是 Dubbo 部署的经典架构图,由注册中心 (服务发现)、配置中心和元数据中心构成了整个服务治理的核心。

2、Dubbo调用流程

对照上面的整体架构图,大致分为以下8大步骤:

1、服务提供者启动,开启Netty服务,创建Zookeeper客户端,向注册中心注册服务;

2、服务消费者启动,通过Zookeeper向注册中心获取服务提供者列表,与服务提供者通过Netty建立长连接;

3、服务消费者通过接口开始远程调用服务,ProxyFactory通过初始化Proxy对象,Proxy通过创建动态代理对象;

4、动态代理对象通过invoke方法,层层包装生成一个Invoker对象,该对象包含了代理对象;

5、Invoker通过路由,负载均衡选择了一个最合适的服务提供者,在通过加入各种过滤器,协议层包装生成一个新的DubboInvoker对象;

6、再通过交换成将DubboInvoker对象包装成一个Reuqest对象,该对象通过序列化通过NettyClient传输到服务提供者的NettyServer端;

7、到了服务提供者这边,再通过反序列化、协议解密等操作生成一个DubboExporter对象,再层层传递处理,会生成一个服务提供端的Invoker对象;

8、这个Invoker对象会调用本地服务,获得结果再通过层层回调返回到服务消费者,服务消费者拿到结果后,再解析获得最终结果。

3、关于Dubbo 服务治理

服务开发框架解决了开发与通信的问题,但在微服务集群环境下,我们仍需要解决无状态服务节点动态变化、外部化配置、日志跟踪、可观测性、流量管理、高可用性、数据一致性等一系列问题,我们将这些问题统称为服务治理

  • 地址发现 :Dubbo 服务发现具备高性能、支持大规模集群、服务级元数据配置等优势,默认提供 Nacos、Zookeeper、Consul 等多种注册中心适配,与 Spring Cloud、Kubernetes Service 模型打通,支持自定义扩展。
  • 负载均衡 :Dubbo 默认提供加权随机、加权轮询、最少活跃请求数优先、最短响应时间优先、一致性哈希和自适应负载等策略
  • 流量路由 :Dubbo 支持通过一系列流量规则控制服务调用的流量分布与行为,基于这些规则可以实现基于权重的比例流量分发、灰度验证、金丝雀发布、按请求参数的路由、同区域优先、超时配置、重试、限流降级等能力。
  • 链路追踪 :Dubbo 官方通过适配 OpenTelemetry 提供了对 Tracing 全链路追踪支持,用户可以接入支持 OpenTelemetry 标准的产品如 Skywalking、Zipkin 等。另外,很多社区如 Skywalking、Zipkin 等在官方也提供了对 Dubbo 的适配。
  • 可观测性 :Dubbo 实例通过 Prometheus 等上报 QPS、RT、请求次数、成功率、异常次数等多维度的可观测指标帮助了解服务运行状态,通过接入 Grafana、Admin 控制台帮助实现数据指标可视化展示。

Dubbo 服务治理生态还提供了对 API 网关、限流降级、数据一致性、认证鉴权等场景的适配支持。

3.1 Dubbo通信协议

Dubbo 从设计上不绑定任何一款特定通信协议HTTP/2、REST、gRPC、JsonRPC、Thrift、Hessian2 等几乎所有主流的通信协议,Dubbo 框架都可以提供支持。 这样的 Protocol 设计模式给构建微服务带来了最大的灵活性,开发者可以根据需要如性能、通用型等选择不同的通信协议,不再需要任何的代理来实现协议转换,甚至你还可以通过 Dubbo 实现不同协议间的迁移。

Dubbo Protocol 被设计支持扩展,您可以将内部私有协议适配到 Dubbo 框架上,进而将私有协议接入 Dubbo 体系,以享用 Dubbo 的开发体验与服务治理能力。

3.2 序列化方式

序列化方式与协议是息息相关的。常用的 Dubbo 序列化方式包括:

  • Hessian2 序列化:Dubbo 默认的序列化方式,性能较差,但兼容性最好。
  • Dubbo 序列化:阿里修改过的 Hessian2,优化了性能。
  • FastJson 序列化:阿里巴巴开源的 JSON 序列化库,性能较好,但是可能会存在兼容问题。
  • Java 原生序列化:性能较差,但是兼容性最好。

3.3 负载均衡算法

当多个provider注册到zk,consumer会选择指定的负载均衡算法自动请求,遇到上线或者下线会重新计算。 常见有四种负载均衡:

  • random :随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
  • roundRobin (默认) :轮询,按公约后的权重设置轮询比率。 存在慢的提供者类即请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
  • leastActive :最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
  • consistentHash :一致性Hash,相同参数的请求总是发到同一提供者。 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动。

4、Dubbo与Spring Cloud关系

4.1 相似之处

Dubbo 和 Spring Cloud 有很多相似之处,它们都在整个架构图的相同位置并提供一些相似的功能:

  • Dubbo 和 Spring Cloud 都侧重在对分布式系统中常见问题模式的抽象(如服务发现、负载均衡、动态配置等),同时对每一个问题都提供了配套组件实现,形成了一套微服务整体解决方案,让使用 Dubbo 及 Spring Cloud 的用户在开发微服务应用时可以专注在业务逻辑开发上。
  • Dubbo 和 Spring Cloud 都完全兼容 Spring 体系的应用开发模式,Dubbo 对 Spring 应用开发框架、Spring Boot 微服务框架都做了很好的适配,由于 Spring Cloud 出自 Spring 体系,在这一点上自然更不必多说。

虽然两者有很多相似之处,但由于它们在诞生背景与架构设计上的巨大差异,两者在性能、适用的微服务集群规模、生产稳定性保障、服务治理等方面都有很大差异。

4.2 差异之处

Spring Cloud 的优势在于:

  1. 同样都支持 Spring 开发体系的情况下,Spring Cloud 得到更多的原生支持
  2. 对一些常用的微服务模式做了抽象如服务发现、动态配置、异步消息等,同时包括一些批处理任务、定时任务、持久化数据访问等领域也有涉猎。
  3. 基于 HTTP 的通信模式,加上相对比较完善的入门文档和演示 demo 和 starters,让开发者在第一感觉上更易于上手

Spring Cloud 的问题有:

  1. 只提供抽象模式的定义不提供官方稳定实现,开发者只能寻求类似 Netflix、Alibaba、Azure 等不同厂商的实现套件,而每个厂商支持的完善度、稳定性、活跃度各异
  2. 有微服务全家桶却不是能拿来就用的全家桶,demo 上手容易,但落地推广与长期使用的成本非常高
  3. 欠缺服务治理能力,尤其是流量管控方面如负载均衡、流量路由方面能力都比较弱
  4. 编程模型与通信协议绑定 HTTP,在性能、与其他 RPC 体系互通上存在障碍
  5. 总体架构与实现只适用于小规模微服务集群实践,当集群规模增长后就会遇到地址推送效率、内存占用等各种瓶颈的问题,但此时迁移到其他体系却很难实现
  6. 很多微服务实践场景的问题需要用户独自解决,比如优雅停机、启动预热、服务测试,再比如双注册、双订阅、延迟注册、服务按分组隔离、集群容错等

而以上这些点,都是 Dubbo 的优势所在

  1. 完全支持 Spring & Spring Boot 开发模式,同时在服务发现、动态配置等基础模式上提供与 Spring Cloud 对等的能力。
  2. 是企业级微服务实践方案的整体输出,Dubbo 考虑到了企业微服务实践中会遇到的各种问题如优雅上下线、多注册中心、流量管理等,因此其在生产环境的长期维护成本更低
  3. 在通信协议和编码上选择更灵活,包括 rpc 通信层协议如 HTTP、HTTP/2(Triple、gRPC)、TCP 二进制协议、rest等,序列化编码协议Protobuf、JSON、Hessian2 等,支持单端口多协议。
  4. Dubbo 从设计上突出服务服务治理能力,如权重动态调整、标签路由、条件路由等,支持 Proxyless 等多种模式接入 Service Mesh 体系
  5. 高性能的 RPC 协议编码与实现
  6. Dubbo 是在超大规模微服务集群实践场景下开发的框架,可以做到百万实例规模的集群水平扩容,应对集群增长带来的各种问题
  7. Dubbo 提供 Java 外的多语言实现,使得构建多语言异构的微服务体系成为可能

5、Dubbo 与 gRPC 关系

Dubbo 与 gRPC 最大的差异在于两者的定位上:

  • gRPC 定位为一款 RPC 框架,Google 推出它的核心目标是定义云原生时代的 rpc 通信规范与标准实现;
  • Dubbo 定位是一款微服务开发框架,它侧重解决微服务实践从服务定义、开发、通信到治理的问题,因此 Dubbo 同时提供了 RPC 通信、与应用开发框架的适配、服务治理等能力。

Dubbo 不绑定特定的通信协议,即 Dubbo 服务间可通过多种 RPC 协议通信并支持灵活切换。因此,你可以在 Dubbo 开发的微服务中选用 gRPC 通信,Dubbo 完全兼容 gRPC,并将 gRPC 设计为内置原生支持的协议之一(推荐的使用模式 Dubbo + gRPC 的组合)。

6、其他常见零散面试问题

6.1 Dubbo 的容错策略有哪些?如何选择?

Dubbo 的容错策略有多种,包括 Failover 容错策略、Failfast 容错策略、Failback 容错策略、Failsafe 容错策略和Forking 容错策略等。在选择容错策略时,需要根据具体的业务场景和需求来选择。

6.2 注册中心宕机,服务间是否可以继续通信?

可以通信的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用。但前提是你没有增加新的服务,如果你要调用新的服务,则是不能办到的。另外如果服务的提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复。

6.3 Dubbo启动时如果依赖的服务不可用会怎样?

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check=“true”,可以通过 check=“false” 关闭检查。

6.4 Dubbo 如何优雅停机?

Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果使用kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行。

6.4 Dubbo 用到哪些设计模式

Dubbo 框架在初始化和通信过程中使用了多种设计模式,可灵活控制类加载、权限控制等功能。

  • 装饰器模式:Dubbo 在启动和调用阶段都大量使用了装饰器模式。以 Provider 提供的调用链为例,具体的调用链代码是在 ProtocolFilterWrapper 的buildInvokerChain 完成的,具体是将注解中含有 group=provider 的 Filter 实现 ,按照 order 排序 ,最后的调用顺序是:EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->ExceptionFilter
  • 观察者模式:Dubbo 的 Provider 启动时,需要与注册中心交互,先注册自己的服务,再 订阅自己的服务,订阅时,采用了观察者模式,开启一个 listener。注册中心会每 5 秒定时检查是否有服务更新,如果有更新,向该服务的提供者发送一个 notify 消息,provider 接受到 notify 消息后,即运行 NotifyListener 的 notify 方法,执行监听器方法。
  • 动态代理模式:Dubbo 扩展 JDK SPI 的类 ExtensionLoader 的 Adaptive 实现是典型的动态代理实现。Dubbo 需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。生成代理类的代码是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法 。代理类的主要逻辑是,获取 URL 参数中指定参数的值作为获取实现类的 key。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1523644.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【C/C++】web服务器项目开发总结【请求 | 响应 | CGI】

博客主页:花果山~程序猿-CSDN博客 文章分栏:Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,背景 二&…

使用 Milvus 和 Streamlit 搭建多模态产品推荐系统

我们可以使用 Milvus 搭建多模态 RAG 应用,用于产品推荐系统。用户只需简单上传一张图片并输入文字描述,Google 的 MagicLens 多模态 Embedding 模型就会将图像和文本编码成一个多模态向量。然后,使用这个向量从 Milvus 向量数据库中找到最相…

C++设计模式——Template Method模板方法模式

一,模板方法模式的定义 模板方法模式是一种行为型设计模式,它先定义了一个算法的大致框架,然后将算法的具体实现步骤分解到多个子类中。 模板方法模式为算法设计了一个抽象的模板,算法的具体代码细节由子类来实现,从…

【Linux】进程状态(RSDT 阻塞 僵尸 孤儿)

目录 进程状态 进程状态的查看 R和S 运行状态 T/t 暂停状态 kill命令 D (disk sleep)状态、 Z 状态(僵尸状态) 孤儿状态 运行状态 阻塞状态 进程状态 一个进程通常有三种状态 ◉ 就绪状态(Ready&#xff0…

如何验证谷歌seo服务商的实力真假?

要验证谷歌SEO服务商的实力真假,可以通过几种简单有效的方法。 你可以要求对方通过视频会议或上门服务,展示谷歌官方后台的真实数据。 通过Google Search Console的实时数据,你可以直接看到他们为客户提供的服务效果,这样的数据是…

【加密社】如何根据.dat文件恢复密钥

加密社 看了这篇指南,你将了解助记词和密钥地址(qianbao)背后的基本原理。 以及,如何找回你的大饼密钥。 Not your key, not your coin 如果你不掌握自己加密货币钱包的私钥,那么你实际上并不能完全控制你的资产 在当今…

【STM32开发笔记】STM32H7S78-DK上的CoreMark移植和优化--兼记STM32上的printf重定向实现及常见问题解决

【STM32开发笔记】STM32H7S78-DK上的CoreMark移植和优化--兼记STM32上的printf重定向实现及常见问题解决 一、CoreMark简介二、创建CubeMX项目2.1 选择MCU2.2 配置CPU时钟2.3 配置串口功能2.4 配置LED引脚2.5 生成CMake项目 三、基础功能支持3.1 支持记录耗时3.2 支持printf输出…

基于FPGA的OV5640摄像头图像采集

1.OV5640简介 OV5640是OV(OmniVision)公司推出的一款CMOS图像传感器,实际感光阵列为:2592 x 1944(即500w像素),该传感器内部集成了图像出炉的电路,包括自动曝光控制(AEC…

内网渗透-域环境搭建

构建内网环境 在学习内网渗透测试时,需要构建一个内网环境并搭建攻击主机,通过具体操作理解漏洞的工作原理,从而采取相应的防范措施。 一个完整的内网环境,需要各种应用程序、操作系统和网络设备,可能比较复杂。我们只需要搭建其中的核心部分,也就是Linux服务器和 Windows服务…

复变函数在大模型中的应用

1. 导入 说来惭愧,我研究生时的研究方向是复分析,但毕业近十年来几乎没用到它。 我还记得实习时做自我介绍时,我说我的研究方向是复分析。面试官不太了解,我便解释说,这是关于对 -1 开平方得到的虚数 i 的研究。 在…

【iOS】——分类拓展关联对象

分类 OC的动态特征允许使用类别为现有的类添加新方法并且不需要创建子类,不需要访问原有类的源代码。通过使用类别即可动态为现有的类添加新方法,而且可以将类定义模块化分布到多个相关文件。 分类是 Objective-C 中的一种语言特性,它允许你…

缓解webclient频繁报‘Connection prematurely closed BEFORE response’的问题

现象: 我在Java代码中使用org.springframework.web.reactive.function.client.WebClient进行网络请求,一开始会有比较多的偶发报错:Connection prematurely closed BEFORE response,网络连接莫名其妙就断了。 处理: …

pm2 + linux + nginx

pm2 pm2是一个用于管理node项目的工具 前言 有如下两个文件 index.js const express require("express"); const app express(); const port 9999;app.get("/index", (req, res) > {res.json({code:200,msg:"songzx001"}) });app.lis…

学习硬件测试06:IIC(SHT30)+HMI串口屏+RS485(modbus)+SPI Flash读写+CAN通信(P81、P91、P95、P120、)

文章以下内容全部为硬件相关知识,鲜有软件知识,并且记的是自己需要的部分,大家可能看不明白。 一、IIC(SHT30 数字温湿度传感器) 1.1实验现象 1、软件模拟 I2C 协议与 SHT30 数字温湿度传感器通讯; &am…

怎么把视频转换成mp4:好用的mp4格式转换器免费版推荐

用手机或者其他拍摄设备记录生活已经成为一种日常,当你想把手机里储存的日常小确幸发布到平台上时,才发现你视频的格式在平台上并不被支持。这个事实难免让人丧气。如果你还想继续上传视频的话,就不得不把视频格式转换成被平台支持的mp4格式。…

ELK系列之一---探索ELK奇妙世界:初识日志界大名鼎鼎的ES集群!

目录 一、为什么要使用ELK 二、ELK简介 三、Elaticsearch入门 3.1、什么是elaticsearch 3.2、elaticsearch的底层优点 3.2.1、全文检索 3.2.2、倒排索引 3.3、elaticsearch集群原理 一、为什么要使用ELK 一般我们需要进行日志分析场景:直接在日志文件中 gre…

Redis从入门到入门(上)

1.Redis概述 文章目录 1.Redis概述1.1 什么是Redis1.2 Redis的应用场景 2.Linux下Redis的安装与使用2.1 Redis下载2.2 Redis的启动2.3 Redis配置2.4 连接Redis 1.1 什么是Redis Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库&#xff0…

C语言sprintf函数使用

1 其函数原型为:int sprintf(char *str, const char *format,...)。 具体用法如下: 基本语法: str:目标字符串的指针,用于存储格式化后的结果。format:格式化字符串,用于指定输出的格式。后续是…

数据结构-队列的介绍及循环队列

1.队列的概念 在开始前,请牢记这句话:队列是一个先进先出的数据结构。 队列(queue)是限定在表的一端进行插入,表的另一端进行删除的数据结构,如同栈的学习,请联系前文所学链表,试想…

4.5SQL注入之加解密注入

SQL注入之加解密注入Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。 Less-21关 Cookie加密注入: 通过Burpsuite抓包: 进行Base64解密: