Dubbo


Dubbo 是什么?

Dubbo 是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。

其核心部分包含:

  • 集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
  • 远程通讯:提供对多种基于长连接的 NIO 框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
  • 自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

Dubbo 和 Spring Cloud 有什么区别?

最大的区别:

  • Dubbo 底层是使用 Netty 这样的 NIO 框架,是基于 TCP 协议传输的,配合以 Hession 序列化完成 RPC 通信;
  • 而 SpringCloud 是基于 Http 协议 + rest 接口调用远程过程的通信,相对来说,Http 请求会有更大的报文,占的带宽也会更多。但是 REST 相比 RPC 更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更为合适,至于注重通信速度还是方便灵活性,具体情况具体考虑。

模块区别:

  • Dubbo 主要分为服务注册中心,服务提供者,服务消费者,还有管控中心;
  • 相比起 Dubbo 简单的四个模块,SpringCloud 则是一个完整的分布式一站式框架,他有着一样的服务注册中心,服务提供者,服务消费者,管控台,断路器,分布式配置服务,消息总线,以及服务追踪等。

Dubbo 核心组件有哪些?

Dubbo 核心组件

  • Provider:暴露服务的服务提供方
  • Consumer:调用远程服务消费方
  • Registry:服务注册与发现注册中心
  • Monitor:监控中心和访问调用统计
  • Container:服务运行容器

Dubbo 都支持什么协议,推荐用哪种?

1、Dubbo 协议:Dubbo 默认使用 Dubbo协议。

  • 适合大并发小数据量的服务调用,以及服务消费者远大于提供者的情况
  • Hessian二进制序列化。
  • 缺点是不适合传送大数据包的服务。

2、rmi 协议:采用 JDK 标准的 rmi 协议实现,传输参数和返回参数对象需要实现 Serializable 接口。使用 java 标准序列化机制,使用阻塞式短连接,传输数据包不限,消费者和提供者个数相当。

  • 多个短连接,TCP 协议传输,同步传输,适用常规的远程服务调用和 rmi 交互操作
  • 缺点:在依赖低版本的 Common-Collections 包,java 反序列化存在安全漏洞,需升级 commons-collections3 到 3.2.2 版本或 commons-collections4 到4.1版本。

3、webservice 协议:基于 WebService 的远程调用协议(Apache CXF 的 frontend-simple 和 transports-http)实现,提供和原生WebService 的互操作多个短连接,基于 HTTP 传输,同步传输,适用系统集成和跨语言调用。

4、http 协议:基于 Http 表单提交的远程调用协议,使用 Spring 的 HttpInvoke 实现。对传输数据包不限,传入参数大小混合,提供者个数多于消费者

  • 缺点是不支持传文件,只适用于同时给应用程序和浏览器 JS 调用

5、hessian:集成 Hessian 服务,基于底层 Http 通讯,采用 Servlet 暴露服务,Dubbo 内嵌 Jetty 作为服务器实现,可与 Hession 服务互操作通讯效率高于 WebService 和 Java 自带的序列化

  • 适用于传输大数据包(可传文件),提供者比消费者个数多,提供者压力较大
  • 缺点是参数及返回值需实现 Serializable 接口,自定义实现 List、Map、Number、Date、Calendar 等接口

6、thrift 协议:对 thrift 原生协议的扩展添加了额外的头信息。使用较少,不支持传 null 值

7、memcache:基于 memcached 实现的 RPC 协议

8、redis:基于 redis 实现的 RPC 协议

Dubbo 服务器注册与发现的流程?

  • 服务容器 Container 负责启动,加载,运行服务提供者。
  • 服务提供者 Provider 在启动时,向注册中心注册自己提供的服务。
  • 服务消费者 Consumer 在启动时,向注册中心订阅自己所需的服务。
  • 注册中心 Registry 返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者 Consumer,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者 Consumer 和提供者 Provider,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心 Monitor。

Dubbo 内置了哪几种服务容器?

三种服务容器:

  • Spring Container
  • Jetty Container
  • Log4j Container

Dubbo 的服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。

Dubbo 负载均衡的作用?

将负载均衡功能实现在 RPC 客户端侧,以便能够随时适应外部的环境变化,更好地发挥硬件作用;而且客户端的负载均衡天然地就避免了单点问题。

它可以从配置文件中指定,也可以在管理后台进行配置修改。

事实上,它支持服务端服务/方法级别、客户端服务/方法级别的负载均衡配置。

Dubbo 有哪几种负载均衡策略,默认是哪种?

Dubbo 提供了 4 种负载均衡实现:

  • RandomLoadBalance:随机负载均衡;随机选择一个,是 Dubbo 的默认负载均衡策略。
  • RoundRobinLoadBalance:轮询负载均衡;轮询选择一个。
  • LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机;活跃数指调用前后计数差,使得慢的 Provider 收到更少请求,因为越慢的 Provider 的调用前后计数差会越大。
  • ConsistentHashLoadBalance:一致性哈希负载均衡;相同参数的请求总是落在同一台机器上。

Dubbo 服务之间的调用是阻塞的吗?

默认是同步等待结果阻塞的,支持异步调用。

Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。

DubboMonitor 实现原理?

Consumer 端在发起调用之前会先走 filter 链;provider 端在接收到请求时也是先走 filter 链,然后才进行真正的业务逻辑处理。默认情况下,在 consumer 和 provider 的 filter 链中都会有 Monitorfilter。

  • MonitorFilter 向 DubboMonitor 发送数据
  • DubboMonitor 将数据进行聚合后(默认聚合 1min 中的统计数据)暂存到ConcurrentMap<Statistics, AtomicReference> statisticsMap,然后使用一个含有 3 个线程(线程名字:DubboMonitorSendTimer)的线程池每隔 1min 钟,调用 SimpleMonitorService 遍历发送
  • statisticsMap 中的统计数据,每发送完毕一个,就重置当前的 Statistics 的 AtomicReference
  • SimpleMonitorService 将这些聚合数据塞入 BlockingQueue queue 中(队列大写为 100000)
  • SimpleMonitorService 使用一个后台线程(线程名为:DubboMonitorAsyncWriteLogThread)将 queue 中的数据写入文件(该线程以死循环的形式来写)
  • SimpleMonitorService 还会使用一个含有 1 个线程(线程名字:DubboMonitorTimer)的线程池每隔 5min 钟,将文件中的统计数据画成图表

Dubbo 有哪些注册中心?

  • Multicast 注册中心:Multicast 注册中心不需要任何中心节点,只要广播地址,就能进行服务注册和发现,基于网络中组播传输实现。
  • Zookeeper 注册中心:基于分布式协调系统 Zookeeper 实现,采用 Zookeeper 的 watch 机制实现数据变更。推荐使用。
  • Redis 注册中心:基于 Redis 实现,采用 key/map 存储,key 存储服务名和类型,map 中 key 存储服务 url,value 服务过期时间。基于
  • Redis 的发布/订阅模式通知数据变更。
  • Simple 注册中心。

Dubbo 的集群容错方案有哪些?

  • Failover Cluster:失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。
  • Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
  • Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks=”2″ 来设置最大并行数。
  • Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息。

Dubbo 超时设置有哪些方式?

Dubbo 超时设置有两种方式:

  • 服务提供者端设置超时时间,在 Dubbo 的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。
  • 服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,会产生警告。

Dubbo 用到哪些设计模式?

1、工厂模式

Provider 在 export 服务时,会调用 ServiceConfig 的 export 方法。ServiceConfig 中有个字段:

private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

Dubbo 里有很多这种代码。这也是一种工厂模式,只是实现类的获取采用了 JDK SPI 的机制。这么实现的优点是可扩展性强,想要扩展实现,只需要在 classpath下增加个文件就可以了,代码零侵入。另外,像上面的 Adaptive 实现,可以做到调用时动态决定调用哪个实现,但是由于这种实现采用了动态代理,会造成代码调试比较麻烦,需要分析出实际调用的实现类。

2、装饰器模式

Dubbo 在启动和调用阶段都大量使用了装饰器模式。以 Provider 提供的调用链为例,具体的调用链代码是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的,具体是将注解中含有 group=provider 的 Filter 实现,按照 order 排序,最后的调用顺序是:

EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->
ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter -> 
ExceptionFilter

更确切地说,这里是装饰器和责任链模式的混合使用。例如,EchoFilter 的作用是判断是否是回声测试请求,是的话直接返回内容,这是一种责任链的体现。而像 ClassLoaderFilter 则只是在主功能上添加了功能,更改当前线程的 ClassLoader,这是典型的装饰器模式。

3、观察者模式

Dubbo 的 Provider 启动时,需要与注册中心交互,先注册自己的服务,再订阅自己的服务,订阅时,采用了观察者模式,开启一个 listener。注册中心会每 5 秒定时检查是否有服务更新,如果有更新,向该服务的提供者发送一个 notify 消息,provider 接受到 notify 消息后,运行 NotifyListener 的 notify 方法,执行监听器方法。

4、动态代理模式

Dubbo 扩展 JDK SPI 的类 ExtensionLoader 的 Adaptive 实现是典型的动态代理实现。Dubbo 需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。生成代理类的代码是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理类主要逻辑是,获取 URL 参数中指定参数的值作为获取实现类的 key。

dubbo 服务挂了,消费端还能用吗?zookeeper 挂了呢


巨人的肩膀:https://github.com/cosen1024/Java-Interview/blob/main/Dubbo

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发飙的蜗牛咻咻咻~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值