【面试】--【Dubbo】

服务发布方(需要依赖dubbo的jar包)

服务调用方(需要依赖dubbo的jar包)

提供多注册中心,不同类型注册中心的支持

注册中心做集群

controller层的负载均衡可以由nginx来实现,由前台页面请求经过nginx分发。从客户端到其他服务的负载均衡可以由dubbo实现loadbalance。

cluster是容错的策略,mock配置的是发生错误后降级处理的类

什么是Dubbo?

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

为什么要用Dubbo?

因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、Zookeeper,保证了高性能高可用性。

使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。

 

Dubbo 和 Spring Cloud 有什么区别?

1)通信方式不同Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。2)组成部分不同

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

dubbo://(推荐)rmi:// hessian:// http:// webservice

Dubbo默认使用什么注册中心,还有别的选择吗?

ZooKeeper,还可以使用redis等,但不推荐使用

Dubbo有哪几种配置方式?

Spring 配置方式 Java API 配置方式

Dubbo 核心的配置有哪些?

 

在Provider 上可以配置的 Consumer 端的属性有哪些?

1)timeout:方法调用超时 2)retries:失败重试次数,默认重试 2 次 3)loadbalance:负载均衡算法,默认随机 4)actives 消费者端,最大并发调用限制

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

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

 

Dubbo推荐使用什么序列化框架,你知道的还有哪些?

推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。

Dubbo默认使用的是什么通信框架,还有别的选择吗?

 

默认使用的是什么通信框架,还有别的选择吗? 默认也推荐使用netty框架,还有mina。

Dubbo有哪几种集群容错方案,默认是哪种?

 

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

 

Dubbo支持服务多协议吗?

Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。

当一个服务接口有多种实现时怎么做?

当一个接口有多种实现时,可以用group 属性来分组,服务提供方和消费方都指定同一个 group 即可。

服务上线怎么兼容旧版本?

可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。

Dubbo可以对结果进行缓存吗?

可以,Dubbo 提供了声明式缓存,用于加速热门数据的访问速度,以减少用户加缓存的工作量。

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

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

Dubbo支持分布式事务吗?

不支持

服务提供者能实现失效踢出是什么原理?

服务失效踢出基于Zookeeper 的临时节点原理

务读写推荐的容错策略是怎样的?

读操作建议使用Failover 失败自动切换,默认重试两次其他服务器。写操作建议使用 Failfast 快速失败,发一次调用失败就立即报错。

Dubbo的管理控制台能做什么?

管理控制台主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。

你还了解别的分布式框架吗?

别的还有Spring cloud、Facebook 的 Thrift、Twitter 的 Finagle 等。

在使用过程中都遇到了些什么问题?

Dubbo 的设计目的是为了满足高并发小数据量的 rpc 调用,在大数据量下的性能表现并不好,建议使用 rmi 或 http 协议。

Dubbo必须依赖的包有哪些?

Dubbo 必须依赖 JDK,其他为可选。

说说Dubbo 服务暴露的过程

 

Dubbo 会在 Spring 实例化完 bean 之后,在刷新容器最后一步发布 ContextRefreshEvent 事件的时候,通知实现了 ApplicationListener 的 ServiceBean 类进行回调 onApplicationEvent 事件方法,Dubbo 会在这个方法中调用 ServiceBean 父类 ServiceConfig 的 export 方法,而该方法真正实现了服务的(异步或者非异步)发布。

Dubbo 能集成 Spring Boot 吗?

可以的

Dubbo如何优雅停机?

 

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

Dubbo需要 Web 容器吗?

不需要,如果硬要用Web 容器,只会增加复杂性,也浪费资源。

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

Spring Container

Jetty Container

Log4j Container

Dubbo 配置文件是如何加载到Spring中的?

Spring容器在启动的时候,会读取到Spring默认的一些schema(提要,纲要)以及Dubbo自定义的schema,每个schema都会对应一个自己的NamespaceHandler,NamespaceHandler里面通过BeanDefinitionParser来解析配置信息并转化为需要加载的bean对象

 

Dubbo SPI 和 Java SPI 区别?

 

JDK SPI JDK 标准的 SPI 会一次性加载所有的扩展实现,如果有的扩展吃实话很耗时,但也没用上,很浪费资源。

所以只希望加载某个的实现,就不现实了

DUBBO SPI 1,对Dubbo进行扩展,不需要改动Dubbo的源码 2,延迟加载,可以一次只加载自己想要加载的扩展实现。3,增加了对扩展点 IOC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。3,Dubbo的扩展机制能很好的支持第三方IoC容器,默认支持Spring Bean。

Dubbo telnet 命令能做什么?

 

dubbo服务发布之后,我们可以利用telnet命令进行调试、管理。Dubbo2.0.5以上版本服务提供端口支持telnet命令

 

超时实现有什么意义

为了避免因为某种原因导致线程被长时间占用,最终出现线程池用完返回拒绝服务的异常。

 

RPC是什么

有同学会说,可以模仿B/S架构的调用方式呀,在B服务暴露一个Restful接口,然后A服务通过调用这个Restful接口来间接调用CalculatorImpl的add方法。

很好,这已经很接近RPC了,不过如果是这样,那每次调用时,是不是都需要写一串发起http请求的代码呢?比如httpClient.sendRequest...之类的,能不能像本地调用一样,去发起远程调用,让使用者感知不到远程调用的过程呢,像这样:

 

@Reference
private Calculator calculator;

...

calculator.add(1,2);

...

这时候,有同学就会说,用代理模式呀!而且最好是结合Spring IoC一起使用,通过Spring注入calculator对象,注入时,如果扫描到对象加了@Reference注解,那么就给它生成一个代理对象,将这个代理对象放进容器中。而这个代理对象的内部,就是通过httpClient来实现RPC远程过程调用的。

可能上面这段描述比较抽象,不过这就是很多RPC框架要解决的问题和解决的思路,比如阿里的Dubbo。

总结一下,RPC要解决的两个问题:

  1. 解决分布式系统中,服务之间的调用问题。
  2. 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

如何实现一个RPC

实际情况下,RPC很少用到http协议来进行数据传输,毕竟我只是想传输一下数据而已,何必动用到一个文本传输的应用层协议呢,我为什么不直接使用二进制传输?比如直接用Java的Socket协议进行传输?

不管你用何种协议进行数据传输,一个完整的RPC过程,都可以用下面这张图来描述

以左边的Client端为例,Application就是rpc的调用方,Client Stub就是我们上面说到的代理对象,也就是那个看起来像是Calculator的实现类,其实内部是通过rpc方式来进行远程调用的代理对象,至于Client Run-time Library,则是实现远程调用的工具包,比如jdk的Socket,最后通过底层网络实现实现数据的传输。

这个过程中最重要的就是序列化反序列化了,因为数据传输的数据包必须是二进制的,你直接丢一个Java对象过去,人家可不认识,你必须把Java对象序列化为二进制格式,传给Server端,Server端接收到之后,再反序列化为Java对象。

下一次我也将通过代码,给大家演示一下,如何实现一个简单的RPC。

RPC vs Restful

其实这两者并不是一个维度的概念,总得来说RPC涉及的维度更广。

如果硬要比较,那么可以从RPC风格的url和Restful风格的url上进行比较。

比如你提供一个查询订单的接口,用RPC风格,你可能会这样写:

/queryOrder?orderId=123

用Restful风格呢?

Get  
/order?orderId=123

RPC是面向过程,Restful是面向资源,并且使用了Http动词。从这个维度上看,Restful风格的url在表述的精简性、可读性上都要更好。

RPC vs RMI

严格来说这两者也不是一个维度的。

RMI是Java提供的一种访问远程对象的协议,是已经实现好了的,可以直接用了。

而RPC呢?人家只是一种编程模型,并没有规定你具体要怎样实现,你甚至都可以在你的RPC框架里面使用RMI来实现数据的传输,比如Dubbo:Dubbo - rmi协议

RPC没那么简单

要实现一个RPC不算难,难的是实现一个高性能高可靠的RPC框架。

比如,既然是分布式了,那么一个服务可能有多个实例,你在调用时,要如何获取这些实例的地址呢?

这时候就需要一个服务注册中心,比如在Dubbo里头,就可以使用Zookeeper作为注册中心,在调用时,从Zookeeper获取服务的实例列表,再从中选择一个进行调用。

那么选哪个调用好呢?这时候就需要负载均衡了,于是你又得考虑如何实现复杂均衡,比如Dubbo就提供了好几种负载均衡策略。

这还没完,总不能每次调用时都去注册中心查询实例列表吧,这样效率多低呀,于是又有了缓存,有了缓存,就要考虑缓存的更新问题,blablabla......

你以为就这样结束了,没呢,还有这些:

  • 客户端总不能每次调用完都干等着服务端返回数据吧,于是就要支持异步调用;
  • 服务端的接口修改了,老的接口还有人在用,怎么办?总不能让他们都改了吧?这就需要版本控制了;
  • 服务端总不能每次接到请求都马上启动一个线程去处理吧?于是就需要线程池;
  • 服务端关闭时,还没处理完的请求怎么办?是直接结束呢,还是等全部请求处理完再关闭呢?
  • ......

如此种种,都是一个优秀的RPC框架需要考虑的问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值