架构问题
1.dubbo的架构设计
- service服务层:用户编写的服务接口和服务实现类。是与实际业务逻辑相关的。
- config配置层:对外的配置接口,封装配置文件中的配置信息,以 ServiceConfig, ReferenceConfig 为中心,分别表示服务提供者和消费者的配置。
- proxy服务代理层:用于生成服务端或者消费者的代理对象,通过代理对象来调用服务。
- registry注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,用于服务的发现和注册。
- cluster路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,选择调用。
- Monitor监控层:每次的调用信息都会发送给监控层,然后由监控层进行记录RPC 调用次数和调用时间监控,以 Statistics 为中心。
- protocol远程调用层:封装RPC调用。
- exchange信息交换:封装请求响应模式,同步转异步。
- transport网络传输层:抽象mina和netty为统一接口。创建客户端和服务端,建立通信连接,是真正传输的数据的地方,基于netty框架实现。
- serialize数据序列化层:将数据进行序列化了再进行传输,传输得到的数据再反序列化。可复用一些工具。
2.dubbo的四大组件
- Provider:服务提供者。
- Consumer:服务消费者。
- Registry:服务注册与发现的中心,提供目录服务,亦称为服务注册中心。
- Monitor:统计服务的调用次数、调用时间等信息的日志服务,并可以对服务设置权限、 降级处理
等,称为服务管控中心。
它们间的关系可以描述为如下几个过程:
- start:dubbo服务启动,spring容器首先会创建服务提供者。
- register:服务提供者创建好后,马上会注册到服务注册中心Registry,这个注册过程称为服务暴露。服务暴露的本质是将服务名称(接口)与服务提供者主机写入到注册中心Registry的服务映射表中。注册中心充当着“DNS域名服务器”的角色。
- subscribe:服务消费者启动后,首先会向服务注册中心订阅相关服务。
- notify:消费者可能订阅的服务在注册中心还没有相应的提供者。当相应的提供者在注册中心注册后,注册中心会马上通知订阅该服务的消费者。但消费者在订阅了指定服务后,在没有收到注册中心的通知之前是不会被阻塞的,而是可以继续订阅其它服务。
- invoke:消费者以同步或异步的方式调用提供者提供的请求。消费者通过远程注册中心获取到提供者列表,然后消费者会基于负载均衡算法选一台提供者处理消费者的请求。
- count:每个消费者对各个服务的累计调用次数、调用时间;每个提供者被消费者调用的累计次数和时间,消费者与调用者都会定时发送到监控中心,由监控中心记录。这些统计数据可以在dubbo的可视化界面看到。
3.dubbo的核心功能
- Remoting:网络通信框架,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。
- Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
- Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
4.dubbo框架源码最重要的设计原则
dubbo在设计时具有两大设计原则:
“微内核+插件”的设计模式。内核只负责组装插件(扩展点),dubbo的功能都是由插件实现的,也就
是 dubbo 的所有功能点都可被用户自定义扩展类所替换。dubbo的高扩展性、开放性在这里被充分体
现。
采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息。简单来说就是,在
dubbo中,所有重要资源都是以URL的形式来描述的。
5. 述dubbo中配置中心与注册中心的关系
dubbo中的注册中心是用于完成服务发现的,而配置中心是用于完成配置信息的统一管理的。若没有专门设置配置中心,系统会默认将注册中心服务器作为配置中心服务器。
6.dubbo内核工作原理的四个构成机制间的关系是怎样的?或者说,一个扩展类实例获取过程是怎样的?
- 获取到该SPI接口的ExtensionLoader。而这个获取的过程会将该SPI接口的所有扩展类(四类)加载并缓存。
- 通过extensionLoader获取到其自适应实例。通常SPI接口的自适应实例都是由Adaptive方法自动生成
的,所以需要对这个自动生成的Adaptive类进行动态编译。 - 在通过自适应实例调用自适应的业务方法时,才会获取到其真正需要的扩展类实例。所以说,一个扩展类实例一般情况下是在调用自适应方法时才创建。
- 在获取这个真正的扩展类实例时,首先会根据要获取的扩展类实例的“功能性扩展名”,从扩展类缓存中找到其对应的扩展类,然后调用其无参构造器,创建扩展类实例instance。
- 通过injectExtension(instance)方法,调用instance实例的setter完成初始化。
- 遍历所有该SPI的Wrapper,逐层包装这个setter过的instance。此时的这个instance,即wrapper实例就是我们需要获取的扩展类实例。
高可用问题
1.dubbo的注册中心宕机,发布者和订阅者之间是否还能通信
消费者还是能够消费dubbo暴露的服务。
原因:
- 注册中心对等集群,任意一台掉了,还是能够自动切换到另一台上。
- 注册中心都挂了,服务提供者和消费者还是可以通过本地缓存实现通讯。
- 监控中心掉线不会影响使用,只是丢失部分采样数据。
- 数据库宕机之后,注册中心仍能通过缓存提供服务列表查询,但是不能注册新的服务。
2.dubbo集群的负载均衡策略
- 基于权重的随机负载均衡机制
随机访问的时候,访问概率等于权重比。 - 基于权重的轮询负载均衡机制
轮询访问的时候,访问概率等于权重比。 - 最少活跃数负载均衡机制
被调用次数越少,其优先级就越高,被调用的概率就越大,尽可能调用相应速度最快的服务提供者。 - 一致性哈希负载均衡机制
根据消费者的请求信息,映射到相应的提供者,相同参数的请求一定会路由到相同的提供者。
3.为什么需要服务治理
服务治理是主要针对分布式服务框架的微服务,处理服务调用之间的关系、服务发布和发现、故障监控
与处理,服务的参数配置、服务降级和熔断、服务使用率监控等。
需要服务治理的情况:
4.dubbo的集群容错方案
- failover cluster
失败自动切换,当出现失败,重试其它的服务器。通常用于读操作,但是重试会带来延迟,可以通过retries=2,来设置重试次数。这是dubbo默认的集群模式。 - failfast cluster
快速失败,发起一次调用,失败了就立即报错。通常用于非幂等性的写操作,比如新增记录。 - failsafe cluster
失败安全,出现异常的时候,直接忽略。通常用于吸入审计日志等操作。 - failback cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。 - forking cluster
并行调用多个服务器,只要一个成功即可返回。通常用于实时性要求高的读操作,但需要浪费更多的资源。可以通过forks= "2",来设置最大并行数。 - broadcast cluster
广播调用所有提供者,逐个调用,任意一台报错,则报错。通常用于通知所有服务提供者更新缓存或日志等本地资源信息。进行同步。
5.dubbo和SpringCloud的关系
dubbo是SOA时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而SpringCloud诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了Spirng、SpirngBoot的优势之上,两个框架在开始目标就不一致,dubbo定位服务治理、SpirngCloud是一个生
态。
二者区别:
最大的区别,dubbo底层是使用Netty这样的NIO框架,是基于TCP协议传输的,配合以Hession序列化完成RPC通信。
而SpringCloud是基于Http协议+Rest接口调用远程过程的通信,相对来说,Http请求会有更大的报文,占的带宽也会更多。但是REST相比RPC更为灵活。
设计问题
1.dubbo支持的列化方式
默认使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。
2.dubbo使用的通信框架
默认使用NIO Netty框架。
3.dubbo的主要应用场景
透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
4.dubbo在安全机制方面的问题
dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。dubbo还提供服务黑白名单,来控制服务所允许的调用方。
5.为什么dubbo使用URL,而不使用JSON,使用URL的优点
首先,dubbo是将URL作为公共契约出现的,即希望所有扩展点都要遵守的约定。既然是约定,那么可以这样约定,也可以那样约定。只要统一就行。所以,在dubbo创建之初,也许当时若采用了JSON作
为这个约定也是未偿不可的。
其次,单从JSON与URL相比而言,都是一种简洁的数据存储格式。但在简洁的同时,URL与dubbo应用场景的契合度更高些。因为dubbo中URL的所有应用场景都与通信有关,都会涉及到通信协议、通信主机、端口号、业务接口等信息。其语义性要强于JSON,且对于这些数据就无需再给出相应的key了,会使传输的数据量更小。
6.dubbo的Wrapper机制
Wrapper机制,即扩展类的包装机制。就是对扩展类中的SPI接口方法进行增强,进行包装,是AOP思想的体现,是Wrapper设计模式的应用。一个SPI可以包含多个Wrapper,即可以通过多个Wrapper对同一个扩展类进行增强,增强出不现的功能。Wrapper机制不是通过注解实现的,而是通过一套Wrapper规范实现的。
Wrapper类是否属于扩展类?
wrapper类仅仅是对现有的扩展类功能上的增强,并不是一个独立的扩展类,所以其不属于扩展类范畴。
什么是SPI?
SPI,Service Provider Interface,服务提供者接口,是一种服务发现机制。其主要是解决面向抽象编程中上层对下层接口实现类的依赖问题,可以实现这两层间的解耦合。
JDK的SPI机制的问题
JDK的SPI机制将所有配置文件中的实现类全部实例化,无论是否能够用到,浪费了宝贵的系统资源。
7.dubbo的Active机制
Activate机制,即扩展类的激活机制。通过指定的条件来实现一次激活多个扩展类的目的。激活机制没有增强扩展类,也没有增加扩展类,其仅仅是为原有的扩展类添加了更多的识别标签,而不像之前的,每个扩展类仅有一个“功能性扩展名”识别标签。其是通过@Active注解实现的。
Activate类是否属于扩展类
Activate机制仅用于为扩展类添加激活标识的,其是通过在扩展类上添加@Activate注解来实现的,所以Activate类本身就是扩展类。
配置问题
1.服务调用超时问题
消费者调用服务超时会引起服务降级的发生,即从发出调用请求到获取到提供者的响应结果这个时间超出了设定的时限。默认服务调用超时时限为 1 秒。可以在消费者端与提供者端设置超时时限来解决。
总的来说还是要设计好业务代码来减少调用时长,设置准确RPC调用的超时时间才能更好的解决这个问题。
超时时间设置:
dubbo超时时间设置有两种方式:
提供者端设置超时时间,在dubbo的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。
消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,会产生警告。
2.dubbo服务注册与发现的基本流程
Provider(提供者)绑定指定端口并启动服务·指供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储。
Consumer(消费者),连接注册中心,并发送应用信息、所求服务信息至注册中心·注册中心根据消费者所求服务信息匹配对应的提供者列表发送至Consumer应用缓存。
Consumer在发起远程调用时基于缓存的消费者列表择其一发起调用。
Provider状态变更会实时通知注册中心、在由注册中心实时推送至Consumer。
这样设计的优点:
- Consumer与Provider解偶,双方都可以横向增减节点数。
- 注册中心对本身可做对等集群,可动态增减节点,并且任意一台宕掉后,将自动切换到另一台。
- 去中心化,双方不直接依懒注册中心,即使注册中心全部宕机短时间内也不会影响服务的调用。
- 服务提供者无状态,任意一台宕掉后,不影响使用。
3.dubbo支持的传输协议,及其应用场景和优缺点
- dubbo 协议 :dubbo 默认传输协议。
连接个数:单连接
连接方式:长连接
协议:TCP
传输方式:NIO 异步传输
适用范围:传入传出参数数据包较小(建议小于 100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。 - rmi:采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable接口,使用java标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议TCP。多个短连接,TCP协议传输,同步传输,适用常规的远程服务调用和rmi互操作。在依赖低版本的Common-Collections包,java序列化存在安全漏洞。
- webservice:基于WebService的远程调用协议,集成CXF实现,提供和原生WebService的互操作。多个短连接,基于HTTP传输,同步传输,适用系统集成和跨语言调用。
- http:基于Http表单提交的远程调用协议,使用Spring的HttpInvoke实现。多个短连接,传输协HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器JS调用。
- hessian:集成Hessian服务,基于HTTP通讯,采用Servlet暴露服务,dubbo内嵌Jetty作为服务器时默认实现,提供与Hession服务互操作。多个短连接,同步HTTP传输,Hessian序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件。
- memcache:基于memcached实现的RPC协议。
- redis:基于redis实现的RPC协议。