【dubbo源码】14. 服务消费方发布之注册consumer

2021-07-16  本文已影响0人  天还下着毛毛雨

前言

前面讲了服务提供方在启动服务的时候会进行服务的发布,启动tcp通信端口,注册到注册中心,监听事件等等

服务消费方在启动的时候也会进行服务的发布:注册到注册中心,开启netty客户端用于调用服务提供方,监听服务列表以及配置变更等。这所有的工作都是在@Reference依赖注入时,创建代理实例时完成的.

1. 代理对象的生成

可以肯定的是@Reference 注入进来的类肯定是一个代理的类,在调用该代理对象的方法时,会走rpc远程调用服务提供方的接口实例的方法。

image image image

利用JDK动态代理对有@Reference的接口进行代理

image

创建InvocationHandler,持有ReferenceBean的引用(就是@Reference里的配置信息)

image

判断容器中是否有referencedBeanName的实例,如果是@Service注解的类就会在spring容器中,否则就是远程应用的接口,进行InvocationHandler的初始化

image

InvocationHandler持有一个对象bean,invoke方法里反射调用的其实是这个bean对象的方法

image

一开始创建InvocationHandler对象时,bean对象肯定没有,需要赋值,调到了referenceBean的get方法

image image

服务消费方启动的所有核心逻辑都在这个ReferceBean的父类的ReferenceConfig.init()方法中

2. ReferenceConfig.init() 消费方启动核心方法

2.1 获取配置

一进来就是检查配置,和服务提供方启动获取配置差不多的逻辑

image

获取application,module,registries,monitor等配置,registries,monitor配置分别以consumer -> module -> application按优先级进行赋值

image
consumer,module,application的来源

这些都是对应的配置类的实例,是从spring容器中获取的,然后赋值

image

`对应的配置信息是怎么变成配置类的bean并注册到spring容器中,可以看【dubbo源码】5.配置信息解析-注解版

2.2 url协议构建

2.1 将配置装到map中

获取到配置之后,把所有的配置都装到一个局部变量map里

image

获取本机的ip :先是从系统变量获取, 再是读网卡,和服务提供方 读本机ip是一样的,读到了也扔到map中

image

最后的map是这样的

image
创建ref的代理
2.2 url协议构建

三种调用方式

  1. 先传入创建一个临时的URL对象

    image
  1. 先判断是不是本地调用

    本地调用指的是不走远程调用,调用本地的服务实例

    配置方式:

    // injvm=true,表示调用该实例方法不走远程
    @Reference(injvm = true)
    private UserService userService;
    
    image

    其他就是判断url中有没有injvm=true,url是根据map生成的,map装的是配置信息,就是判断你的injvm配置是否为true

    image

    如果是本地调用,将会生成一个injvm协议url,利用url的协议头injvm获取protocol对应的实现类InjvmProtocol的refer()方法进行invoker对象的创建

    injvm://127.0.0.1/com.lb.dubbo_api.service.UserService?application=dubbo-c&dubo=2.0.2&injvm=true
    &interface=com.lb.dubbo_api.service.UserService&methods=getUser
    &pid=7848&register.ip=192.168.100.72&side=consumer&timestamp=1626427621131
    
    image
  2. 先判断是不是点对点调用

    点对点调用指的是在@Reference配置url参数,指定调用这个url主机的服务实例方法

    image
  3. 走注册中心

    根据注册中心配置,构建registry协议URL,并把当前消费者的配置信息,配置到每一个注册协议中

    image
    1. 单注册中心创建一个invoker对象

      image
    2. 多注册中心创建多个invoker对象,并包装到StaticDirectory对象中

      image

2.3 refprotocol.refer(interfaceClass, url) 创建Invoker对象

这个方法很重要,包含了很多功能要点

refprotocol对象的来源 - spi机制
image

获取到的先是javaassist生成的类,然后refer代码里根据extName获取到的肯定是一个Protocol的包装类对象,并且最里面的实例根据现在的url是注册协议,获取到的会是RegisrtyProtocol ,【dubbo源码】7.dubbo的spi机制源码

image

跟服务提供方发布时的调用流程差不多,这三个类具体是干嘛的,可以看这个【dubbo源码】9. 服务提供方发布之netty服务端启动

image

最后调用到 RegisrtyProtocol的refer方法

image

在调到dorefer方法

image
  1. 消费者注册

    comsumer协议

    consumer://192.168.100.72/com.lb.dubbo_api.service.UserService?application=dubbo-c&category=consumers&check=false
    &dubbo=2.0.2&interface=com.lb.dubbo_api.service.UserService&methods=getUser&pid=14024&side=consumer&timestamp=1626430401334
    

    往zk里写入协议

    image image

    利用zk客户端api往/dubbo/com.lb.dubbo_api.service.UserService/consumers节点下写数据

    image

    通过toUrlPath(url)获取真正要注册到zk的url

    // 节点路径
    /dubbo/com.lb.dubbo_api.service.UserService/consumers
    // 节点数据
    consumer%3A%2F%2F192.168.100.72%2Fcom.lb.dubbo_api.service.UserService%3F
    application%3Ddubbo-c%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.2%26interface%3Dcom.lb.dubbo_api.service.UserService%26
    methods%3DgetUser%26pid%3D14024%26side%3Dconsumer%26timestamp%3D1626430401334
    

    查看该zk节点

    image
上一篇 下一篇

猜你喜欢

热点阅读