开发者学堂课程【阿里巴巴分布式服务框架 Dubbo 快速入门:服务引用流程】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/624/detail/9480
服务引用流程
内容介绍:
一、引入
二、以 debug 的模式来启动
三、总结
一、引入
如何通过配置 reference 标签远程引用刚才暴露的服务?前置的流程与服务暴露还是一样,每一个标签对应一个解析类,而 reference 标签对应的是 referencebean,Bean 有一个特殊之处,它是 FactoryBean,即 spring 的工厂 Bean,也就是说要获取 reference 标签里的组件(user service),
Public class OrderServiceImpl implements OrderService{
@Autowired
UserService userService;
自动注入 userService,自动注入的 service 从容器中找,因为它是一个工厂 Bean,那 referencebean 就会调用工厂 bean 给它 object 方法。(这个方法呢打一个断点),它返回的对象就会作为标签配置返回的对象。
二、以 debug 的模式来启动
启动,第一步先到 get 方法:
Public object getObject() throws Exception{
Return get():
}
在 Autowired 想要获取 user service,获取 user service,调用工厂 Bean的get object 获取。
Stepinto get 方法,有一段判断,destroy 是否销毁,
If (ref==null){
Init();
{
Return ref;
{
如果 ref 引用是空的,初始化(打一个断点,放行到这里)。step into 看一下初始化是什么样的一个流程。
前面都是一些信息检查,包括一些获取属性,主要在下面有一个方法有一个叫 create proxy 创建代理对象,比如说在前面检查一大堆属性,设置一堆后来放行。
创建什么代理对象,这有一个 map ,里面写了好多的属性,比如注册中心的地址是什么,想要调的方法,包括想要调的接口,相当于是创建这些信息给代理对象。
如何创建代理对象:
首先,在创建对象时引入一个 url 的地址,名称为 reference protocol
If (urls.size()==1){
Invoker = refprotocol.refer(interfaceClass,urls.get(0)_;
}else{
比如引用的协议要来远程引用,有一个接口是 user service,要以远程引用这个接口。
远程的引用,首先url里保存注册中心的地址,也就是从注册中心要来获取远程接口。
获取还是 protocol,主要核心两个,一个是 dubbo,由于是用 dubbo 的协议来进行调用的,所以看 dubbo 的 reference 方法。
//create rpc invoker.DubboInvoker<T>invoker=new DubboInvoker<T>(serviceType,url,getClients(url),invokers);
同样 protocol 里再来打开注册中心的 refer,
Public <T>Invoker<T>refer(Class<T>type,URL url)throws RpcException{
相当于有两个 refer 方法。暴露之前用 protocol 来调用 refer,直接放行到每一个 protocol,看它怎么进行远程引用。放行先来到注册中心的 refer 方法来引用,先得到注册,根据注册中心地址,得到注册中心的信息,获取到了注册中心的一些信息以后,还是获取一些 qs string 查询字符串,注册中心里边的要调的参数。
获取完以后,有一个 doRefer,注册中心的 doRefer 想做远程引用(此处会传入几个东西,一个是注册中心的地址,还有远程要引用的 userservice,以及注册中心的原来地址),step into 发现 doRefer 帮助创建一些东西。
有一个方法叫 directory subscribe,也就是开始去注册中心订阅服务提供者提供的服务。订阅服务的同时,会进入到 Dubboprotocol 里,dubboprotocol 去执行远程引用。执行远程引用的核心有一个叫 getClients,获取客户端。
也就是 Dubbo 想要远程引用 user service,刚在注册中心里订阅到 userservice 的地址,其次包括 invoker,执行者现在是空的,要先获取客户端,最终返回真正的执行者。
核心在获取客户端,当 dubbo protocol 远程引用的时候,获取客户端是是帮助创建一客户端,而且是根据连接数,有多条还可以创多个。此外一个叫获取共享的客户端:getSharedClient,拿到 url 地址,
ExchangClient exchangeClient=initClient(url);
会有一个叫初始化客户端。初始化客户端获取到 url 地址,相当于 dubbo 协议要远程调用20882端口。有一个叫 exchanger connect,要进行连接。
看到用 exchange 进行 connect 连接:
Return getExchanger(url).connect(url,handler) connect 打开,发现连接调用 transporters connect transporters 就是传输器连接呢。拿到传输器连接又到达了 Netty 的底层。
相当于创建一个 Netty 的客户端,用 url 的地址监听一个端口,也就是创建出一个连接。创建出来以后,包装好的 Invoker 就会返回过来,有客户端的连接属性。整个 Invoker 相当于调用 protocol reference 包装,包装以后会返回 Invoker。
放行返回 Invoker,就订阅完成。注册中心的 Invoker 就返回了,相当于封装了真正的目标的 Invoker,有目标的调用的地址,包括配置、消费者的地址,Invoker 里它知道要调用哪一个。
之后给提供者和消费者的注册表里把 Invoker 注册进去,注册成 url 的地址就是订阅的 url 地址,相当于消费者消费哪个服务,就把注册进去,提供者的 url 地址对应的是什么,消费者原来地址对应是什么,也就是每一个 Invoker 都保存好返回。 dorefer 执行完以后,完全返回, createProxy 创建对象就完成了。
创建对象里封装了 invoker,比如要调用远程服务,用一个 Invoker 封装了远程服务的调用信息,包括 Invoker 的代理对象,并且代理对象创建好以后,都进行了存储。相当于引用就有一个代理对象。
三、总结
整个流程如图:
1.ReferenceBean 是远程引用服务的 bean,它是一个工厂 Bean,所以在获取引用对象的时候,会要调用工厂的 get object。然后,get 初始化,主要是创建对象,就是 protocol 引用远程服务。
以两个 protocol,是 dubboprotocol 和 registry protocol 来引用, dubbo protocol 负责跟远程20880端口服务器来进行连接,创建一个客户端,而它就负责从注册中心订阅出服务,并且把 Invoker 创建的客户端信息,都保存到注册表中。
整个 Invoker 封装好以后返回, Invoker 的代理对象创建整完了以后,再返回,相当于远程引用的 service,就是返回的代理对象。
2、核心就是代理对象里有跟远程能建起连接的客户端,也有远程服务的每一个 URL 地址信息。
3、如何远程调用服务
客户端与服务器建起连接,再来调服务。