美文网首页
【dubbo源码】14. 服务消费方发布之注册consumer

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

作者: 天还下着毛毛雨 | 来源:发表于2021-07-16 18:44 被阅读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协议构建

    三种调用方式

    • 本地调用
    • 点对点调用,@Reference配置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对象

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

    • 注册consumer
    • 监听providers,configurators,routers节点的变化 : 动态修改配置,刷新服务列表,路由过滤
    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

    相关文章

      网友评论

          本文标题:【dubbo源码】14. 服务消费方发布之注册consumer

          本文链接:https://www.haomeiwen.com/subject/sdibpltx.html