天天看点

dubbo详细学习笔记

dubbo详细学习笔记

第一章 基本概念

1. 什么是dubbo

dubbo是一款高性能的RPC框架,可以和Spring框架无缝集成。dubbo提供了三大核心能力,面向接口的远程方法调用,智能容错和负载均衡以及服务自动注册和发现

具体介绍参考dubbo官网:dubbo官网

2. 什么是RPC

RPC即远程过程调用,比如两台服务器A和B,A服务器上部署一个应用,B服务器部署一个应用,A服务器上的应用调用B服务器上的应用提供的方法,由于两个应用不在一个内存空间,不能直接调用,所以需要通过网络来表达调用的语义和传达调用的数据。RPC框架比较多,像RMI,Hessian,gRPC ,dubbo等,核心模块就是网络通讯和序列化。

dubbo详细学习笔记

RPC调用过程图如下:

dubbo详细学习笔记

3. RMI

(1)概念

RMI是java原生支持的远程调用,采用JRMP作为通信协议,可以认为是java版本的分布式远程调用方案。

(2)核心概念

dubbo详细学习笔记

(3)RMI实现步骤

① 创建远程接口,并且继承java.rmi.Remote接口

② 实现远程接口,并且继承UnicastRemoteObject

③ 创建服务器程序,createRegistry()方法注册远程对象

④ 创建客户端程序,获取注册信息,调用接口方法

具体实现如下:

dubbo详细学习笔记
dubbo详细学习笔记
dubbo详细学习笔记
dubbo详细学习笔记

4. Hessian

(1)Hessian使用C/S方式,基于HTTP协议传输,使用Hessian二进制序列化

(2)具体实现

server端,为war包,需要配置web.xml

① 导入依赖

dubbo详细学习笔记

② 创建接口

dubbo详细学习笔记

③ web.xnl

dubbo详细学习笔记

客户端

① 添加Hessian依赖

② 创建server端相同的接口,客户端需要用到服务端的接口

③ 创建测试类进行测试

dubbo详细学习笔记

第二章 dubbo高可用

1. 集群容错

(1)服务路由

服务路由包含一条路由规则,决定了服务消费者的调用目标,规定了服务消费者可调用哪些服务提供者

① [服务消费者匹配条件]=>[服务提供者匹配条件]

例如:host=10.20.152.10=>host=10.20.153.11

表示IP为10.20.152.10的服务消费者只可调用IP为10.20.153.11机器上的服务

② 常用路由配置

白名单

host!=10.20.152.10,10.20.152.11=>

表示除了这两个其他都可以调用

黑名单

host=10.20.152.10,10.20.152.11

这两个ip不能进行消费,服务禁用

读写分离

method=find,list,get,is=>host=172.22.3.94,172.22.3.9,172.22.3.96

method!=find,list,get,is=>host=172.22.3.97,172.22.3.98

前后台分离

application=front=>host=172.22.3.92,172.22.3.93

application!=front=>host=172.22.3.92,172.22.3.93

(2)集群容错

① Failover Cluster失败自动切换,当出现失败,重试其他服务器,通常用于读操作,可通过retries=“2”设置重试次数

<dubbo :server retries=“2”/>或<dubbo :reference retries=“2”/>

② Failfast Cluster快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作,比如新增记录

③ Failsafe Cluster 失败安全,出现异常时,直接忽略,通常用于写入日志等操作

④ Failback Cluster失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作

⑤ Forking Cluster 并行调用多个服务器,只要一个成功即返回,通常用于实时性要求较高的读操作,可通过forks="2"来设置最大并行数

⑥ Broadcast Cluster广播调用所有提供者,逐个调用,任意一台报错则报错,通知用于通知所有提供者更新缓存或日志等本地资源信息

(3)负载均衡

① Random LoadBalance:按照权重设置随机概率,无状态

② RoundRobin LoadBalance:轮询,有状态

③ LeastActive LoadBalance:最少活跃数随机,方法维度的统计服务调用数

④ ConsistentHash LoadBalance:一致性Hash

2. 服务治理

(1)服务降级

服务提供方的编写:

dubbo详细学习笔记
dubbo详细学习笔记

① dubbo配置-application.xml

dubbo详细学习笔记

② 提供方接口实现暴露的接口

dubbo详细学习笔记

③ web.xml 设置监听

dubbo详细学习笔记

服务消费者的编写

① 配置文件-application.xml

dubbo详细学习笔记

② 编写web.xml

dubbo详细学习笔记

③ controller层代码

dubbo详细学习笔记

mock配置方式

mock的配置支持两种,一种是boolean值,默认的为false,配置为true,则缺省使用mock类名,即类名+Mock后缀;另外一种是配置“return null”,可以简单的忽略掉异常

① mock配置在消费方,当消费方正常运行,获取返回值时为null

dubbo详细学习笔记

② mock=“return null”会对service中的所有方法做统一处理。都返回null值,如果我们要做其他处理则配置mock=“true”,同时实现mock接口,接口名+Mock后缀,如果调用失败则会嗲用Mock实现,mock实现需要保证无参的构造方法

dubbo详细学习笔记

在暴露的接口编写Mock实现类

dubbo详细学习笔记

3. 高可用整合Hystrix

(1) 添加依赖

dubbo详细学习笔记

(2)在主程序启动类上添加注解@EnableHystrix开启Hystrix功能

dubbo详细学习笔记

(3)在提供方增加@HystrixCommand注解,这样调用会经过Hystrix代理

dubbo详细学习笔记

(4)在消费方增加@HystrixCommand注解并指定出错是的回调方法,当出错时,会调用fallbackMethod里的方法

dubbo详细学习笔记

4. dubbo线程IO模型

(1)BIO:每个客户端连接过来后,服务端会启动一个线程去处理该客户端的请求,阻塞I/O的通信

dubbo详细学习笔记

在传统的IO模型中,每个连接创建成功之后都需要一个线程来维护

(2)NIO:非阻塞IO,新来一个连接不在创建一个新的线程,而是把这条连接直接绑定到某个固定的线程,然后这条连接所有的读写都由这个线程负责

对比两种IO

dubbo详细学习笔记

说明:

① IO模型中,一个连接对应创建一个线程,对应一个死循环,死循环的目的就是不断监测这条连接上是否有数据可读,但是在大多数情况下,很多个while循环都白白浪费,没有数据

② NIO模型中可以把这么多的while死循环变成一个死循环,这个死循环由一个线程控制,这就是NIO模型中的选择器的作用,一条连接来了,不是创建一个while死循环去监听是否有数据可读了,而是直接把这条连接注册到选择器上,通过检查这个选择器,就可以批量监测出有数据可读的连接,进而读取数据

5. dubbo原理

dubbo详细学习笔记

说明:

① config配置层:对外配置接口,以ServiceConfig,ReferenceConfig为中心,可以直接初始化配置类也可以通过spring解析配置生成配置类

② proxy服务代理层:服务接口透明代理,生成服务的客户端stub和服务器端skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory

③ registry注册中心:封装服务地址的注册于发现,以服务URL为中心,扩展接口为RegistryFactory,Registry,RegistryService

6. dubbo SPI机制

(1)具体实现

① 新建一个接口和实现类

dubbo详细学习笔记

② dubbo SPI所需的配置文件放置在META-INF/dubbo路径下,其文件的包路径要和service的包路径一致,文件内容如下:根据key来进行访问的

dubbo详细学习笔记

③ 进行测试

dubbo SPI的相关逻辑被封装在ExtensionLoader类中,通过ExtensionLoader,我们可以加载指定的实现类,这里需要注意的是需要在接口上标注@SPI注解,根据key来对应访问具体的实现类

dubbo详细学习笔记

(2)源码分析

① 通过getExtensionLoader方法获取一个ExtensionLoader实例,该方法先从缓存中获取与扩展类对应的ExtensionLoader,若缓存未命中,则创建一个新的实例

dubbo详细学习笔记

② getExtension方法中,检查缓存,未命中则调用createExtension方法创建扩展对象

dubbo详细学习笔记

③ createExtension方法包含如下步骤:

通过getExtensionClasses获取所有的扩展类

通过反射创建扩展对象

向扩展对象中注入依赖

将扩展对象包裹在相应的Wrapper对象中

dubbo详细学习笔记

injectExtension方法依赖注入实现原理:dubbo首先会通过反射获取到实例的所有方法,然后在遍历方法列表,检测方法名是否具有setter方法特征,若有,则通过ObjectFactory获取依赖对象,最后通过反射调用setter方法将依赖设置到目标对象中

dubbo详细学习笔记

7. dubbo服务暴露源码分析

(1)spring容器启动,会加载BeanDefinitionParser类来解析配置文件,dubbo配置文件的加载依赖实现类DubboBeanDefinitionParser,DubboBeanDefinitionParser解析器会将配置文件中不同的标签解析成不同的xxxConfig,<dubbo:service/>,<dubbo:reference/>分别解析成serviceBean和referenceBean

dubbo详细学习笔记

(2)serviceBean实现了InitializingBean和ApplicationListener接口,在afterPropertiesSet方法中主要将配置文件中属性依次配置到对应的bean中,在spring上下文刷新事件后会回调onApplicationEvent方法

dubbo详细学习笔记

(3)调用父类ServiceConfig对象的export方法,检查延迟是否导出,执行doExportUrls

dubbo详细学习笔记

(4)doExportURLs方法首先通过loadRegistries加载注册中心链接,后在遍历ProtocolConfig集合导出每个服务,并在导出服务的过程中,将服务注册到注册中心

dubbo详细学习笔记

(5)doExportUrlsForProtocol方法主要将版本,时间戳,方法名以及各种配置对象的字段信息放入到map中,map中的内容将作为URL的查询字符串,构建好map后,紧接着是获取上下文路径,主机名和端口号信息,最后将map和主机名等数据传给URL构造方法创建RUL对象

dubbo详细学习笔记

(6)导出服务

scope=none则不做处理,scope!=remote导出本地服务,scope!=local则导出远程服务,不管哪一种导出服务,都需要创建Invoke对象,它是ProxyFactory代理工厂创建的对象,invoke封装了调用实体,根据scope参数,决定导出服务到本地还是远程

8. dubbo服务引入

(1)引入时机

① 在spring容器调用ReferenceBean的afterPropertiesSet方法时引用服务,饿汉式的

② 在ReferenceBean对应的服务被注入到其他类中的引用,懒汉式的

默认情况下dubbo使用懒汉式服务,可以通过配置dubbo:reference的init属性进行重启

继续阅读