Dubbo源码(5)-领域模型及调用流程

Dubbo集群容错策略和动态代理策略 这就需要spi了,需要根据指定的配置或者是默认的配置,去找到对应的实现类加载进来,然后才可以调用到这个实现类的实例对象。注解标注了方法,在运行的时候会针对Protocol生成代理类,这个代理类在运行的时候动态根据url中的 protocol来获取那个key,默认是dubbo,也可以自己指定,如果指定了别的key,就会获取别的实现类的实例。这行配置,接着会根据配置使用定义好的MyProtocol了,通过上述方式,可以替换掉大量的dubbo内部的组件,写一个自己的jar包,然后配置一下即可。 阅读详情

本文主要参考自Dubbo官方文档、Dubbo项目源码以及网络文章和相关书籍,并附上自身的一些理解,如有遗漏或错误,还望海涵并指出。谢谢!

------本文基于Dubbo-2.6.1版本

一.Dubbo中的动态代理

1.1、Dubbo Invoker领域模型

在说Dubbo动态代理之前,先来看看Dubbo的Invoker领域模型。

任何框架或组件,总会有核心领域模型,比如:Spring 的 Bean,Struts 的 Action,Dubbo 的 Service,Napoli 的 Queue 等等。这个核心领域模型及其组成部分称为实体域,它代表着我们要操作的目标本身。实体域通常是线程安全的,不管是通过不变类,同步状态,或复制的方式。

服务域也就是行为域,它是组件的功能集,同时也负责实体域和会话域的生命周期管理, 比如 Spring 的 ApplicationContext,Dubbo 的 ServiceManager 等。服务域的对象通常会比较重,而且是线程安全的,并以单一实例服务于所有调用。

什么是会话?就是一次交互过程。会话中重要的概念是上下文,什么是上下文?比如我们说:“老地方见”,这里的“老地方”就是上下文信息。为什么说“老地方”对方会知道,因为我们前面定义了“老地方”的具体内容。所以说,上下文通常持有交互过程中的状态变量等。会话对象通常较轻,每次请求都重新创建实例,请求结束后销毁。

简而言之:把元信息交由实体域持有,把一次请求中的临时状态由会话域持有,由服务域贯穿整个 过程。

在这里插入图片描述

百度中关于领域模型的解释:

领域模型是对领域内的概念类或现实世界中对象的可视化表示。 又称概念模型、领域对象模型、分析对象模型。 它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。

Invoker是Dubbo 领域模型中非常重要的一个概念,很多设计思路都是向它靠拢。这就使得Invoker渗透在整个实现代码里。而Invoker的实现是基于动态代理的,这也是本文要讲解的重点。

1.2、Invoke在RPC过程中的作用

在整个Dubbo关于RPC通信过程的代码中出现了很多个Invoker,Invoker直译为执行器,那么这些Invoker的作用是什么呢?

下面来看一张图,简化了Dubbo RPC过程中的其他组件,来直观地看Invoker在这个过程中的作用:

在这里插入图片描述

可以看出,在服务提供端中,Invoker封装了具体的实现服务类。

当服务消费端需要通过RPC调用这个服务时,生成proxy调用对应的Invoker,借助网络通知到服务提供端Exporter,然后Exporter调用Invoker执行具体的服务逻辑。

可以看出,Invoker实质上就是由动态代理生成并封装了网络连接和数据处理的逻辑,以屏蔽底层的实现。这就是DUbbo动态代理技术的实际运用了。

二.RPC调用流程

在看源码之前,先来从宏观的层面了解下整个调用的流程,这里忽略了很多细节,只展示最重要的实现,如下图:

在这里插入图片描述

整体的流程如下:

  1. 客户端通过RPC调用Service接口的方法
  2. 通过动态代理生成一个Proxy代理对象,该对象实现了Service接口,内容大致如下:
public class proxy0 implements ClassGenerator.DC, EchoService, Service {
    public static Method[] methods;
    private InvocationHandler handler
    public void bye(Object paramObject) {
       Object[] arrayOfObject = new Object[1];
       arrayOfObject[0] = paramObject;
       Object localObject = this.handler.invoke(this, methods[0], arrayOfObject);
    }
    public String hello(String paramString){ Object[] arrayOfObject = new Object[1];
       arrayOfObject[0] = paramString;
       Object localObject = this.handler.invoke(this, methods[1], arrayOfObject);
       return (String)localObject;
    }
    public Object $echo(Object paramObject) {
       Object[] arrayOfObject = new Object[1];
       arrayOfObject[0] = paramObject;
       Object localObject = this.handler.invoke(this, methods[2], arrayOfObject);
       return (Object)localObject;
    }
    public proxy0() {
        public proxy0(InvocationHandler paramInvocationHandler) {
            this.handler = paramInvocationHandler; 
        } 
    }

该类通过dubbo-common模块的bytecode模块的 Proxy类使用Javassis动态代理技术生成。

代理类首先实现了Service接口,然后所有的重写方法调用都是集中在了InvocationHandler的invoke方法中执行,这里实质上就是调用了代理对象(封装了许多RPC细节)。

  1. 服务端接的Protocol收到了这个RPC调用。
  2. Protocol获取到被调用的Exporter对象
  3. Exporter对象获取到Invoker代理对象
  4. Invoker代理对象执行Wrapper包装类对象中对应的方法。实质上Wrapper对象内含有Service实现对象,如以下代码:
public class Wrapper1 extends Wrapper implements ClassGenerator.DC
{
       public static String[] pns;
       public static Map pts;
       public static String[] mns;
       public static String[] dmns;
       public static Class[] mts0;
       public static Class[] mts1;
       public static Class[] mts2;

       public String[] getPropertyNames()
       {
         return pns;
       }

       public boolean hasProperty(String paramString)
       {
         return pts.containsKey(paramString);
       }

       public Class getPropertyType(String paramString)
       {
         return (Class)pts.get(paramString);
       }

       public String[] getMethodNames()
       {
         return mns;
       }

       public String[] getDeclaredMethodNames()
       {
         return dmns;
       }

       public void setPropertyValue(Object paramObject1, String paramString, Object paramObject2)
       {
         ServiceImpl w;
         try
         {
           w = (ServiceImpl)paramObject1;
         }
         catch (Throwable localThrowable)
         {
           throw new IllegalArgumentException(localThrowable);
         }
         if (paramString.equals("test01"))
         {
           w.test01 = ((String)paramObject2);
           return;
         }
         if (paramString.equals("demoDAO"))
         {
           localServiceImpl.setDemoDAO((DemoDAO)paramObject2);
           return;
         }
         throw new NoSuchPropertyException("Not found property \"" + paramString + "\" filed or setter method in class com.alibaba.dubbo.demo.provider.ServiceImpl.");
       }

       public Object getPropertyValue(Object paramObject, String paramString)
       {
         ServiceImpl w;
         try
         {
           w = (ServiceImpl)paramObject;
    }
    catch (Throwable localThrowable)
        {throw new IllegalArgumentException(localThrowable);
        }
        if (paramString.equals("test01")) {return localServiceImpl.test01;
        }
        throw new NoSuchPropertyException("Not found property \"" + paramString + "\" filed or setter method in class com.alibaba.dubbo.demo.provider.ServiceImpl.");
    }
    public Object invokeMethod(Object paramObject, String paramString, Class[] paramArrayOfClass, Object[] paramArrayOfObject)
    throws InvocationTargetException
      {ServiceImpl w;
      try
    {
        w = (ServiceImpl)paramObject;
    }
      catch (Throwable localThrowable1)
      {
        throw new IllegalArgumentException(localThrowable1);
      }
      try
    {
        if ("hello".equals(paramString) && paramArrayOfClass.length == 1) {
            return w.hello((String)paramArrayOfObject[0]);
        }
        if ("bye".equals(paramString) && paramArrayOfClass.length == 1)
        {w.bye((Object)paramArrayOfObject[0]);
        return null;
        }
        if ("setDemoDAO".equals(paramString) && paramArrayOfClass.length == 1)
        {w.setDemoDAO((DemoDAO)paramArrayOfObject[0]);
        return null;
        }
    }
      catch (Throwable localThrowable2)
    {
        throw new InvocationTargetException(localThrowable2);
    }
      throw new NoSuchMethodException("Not found method \"" + paramString + "\" in class com.alibaba.dubbo.demo.provider.ServiceImpl.");
    }
}

该包装类由dubbo-common模块的bytecode模块的Wrapper类使用Javassist动态代理技术生成。

可以看到到了这一步,其实就是在调用包装类中包装的实现类的具体方法了。

Java 领域 Dubbo 服务注册与发现机制详解 本文旨在深入解析 Dubbo 框架中的服务注册与发现机制,帮助开发者理解 Dubbo 微服务架构的核心工作原理。内容涵盖从基础概念到高级特性,包括注册中心的选择、服务元数据管理、健康检查机制等。文章将从 Dubbo 的基本架构开始,逐步深入服务注册与发现的实现细节,包括核心组件、交互流程、源码分析和实战案例,最后讨论最佳实践和未来趋势。服务提供者(Provider): 暴露服务的服务端应用服务消费者(Consumer): 调用远程服务的客户端应用注册中心(Registry): 服务注册与发现的核心组件。 阅读详情

相关推荐

深入剖析:NAND Flash与SD NAND(贴片式SD卡)存储扇区分配表架构差异与优化策略

本文深入探讨了NAND Flash与SD NAND(贴片式SD卡)在存储技术中的架构差异及其优化策略。NAND Flash作为非易失性存储器,依赖主控芯片进行坏块管理和磨损均衡,而SD NAND则通过内置控制器和标准文件系统(如FAT)简化了存储管理。两者在写入性能、容量扩展和可靠性方面各有优劣,NAND Flash需通过磨损均衡和写入合并优化性能,而SD NAND则通过高容量和高速传输提升效率。文章为嵌入式系统开发者和硬件工程师提供了关于如何根据需求选择并优化存储介质的参考。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1240

Dubbo源码解析-动态代理JDK篇

前言: 有关于动态代理,是一个长盛不衰的话题。无论是面试还是各个框架的应用,都是热点话题。 而关于Dubbo的动态代理,有两种实现方式:一种是JDK,另一种是Javassist。 本文来介绍下JDK动态代理的使用方式,并简单分析下其源码实现。 1.JDK动态打理示例 1.1 创建接口及实现类 // 接口 public interface Subject { String say(String name); } // 实现类 public class Rea...

恐龙弟旺仔的博客 1439

从零到一:手把手教你用YonBuilder for NCC搭建NC Cloud 2021.11开发环境(含避坑指南)

本文详细指导如何使用YonBuilder for NCC搭建NC Cloud 2021.11开发环境,涵盖硬件要求、软件安装、YonBuilder配置及常见故障排除。特别提供避坑指南,帮助开发者快速上手NCC开发,确保环境配置的原子化分解和开发思维的体系化建立。

weixin_42523326的博客 347

Dubbo源码(6)-动态代理技术源码解析

文章目录一.Dubbo中的动态代理1.1、Dubbo Invoker领域模型1.2、Invoke在RPC过程中的作用二.RPC调用流程三.动态代理相关源码解析3.1、ProxyFactory3.1.1、AbstractProxyFactory3.1.2、JavassistProxyFactory3.2、InvokerInvocationHandler3.3、AbstractProxyInvoker3.4、bytecode包 本文主要参考自Dubbo官方文档、Dubbo项目源码以及网络文章和相关书籍,并附上

BoringError的博客 2004

微信取证不求人:最新免费DAT解码工具使用指南(含闪退解决方案)

本文提供了一份详细的微信DAT文件免费解码工具使用指南。针对用户常见的图片无法查看问题,手把手教学如何安全获取并操作开源图形化工具,将加密的DAT文件一键还原为JPG/PNG图片。文章重点剖析了DAT文件的加密原理,并给出了详细的步骤解决工具运行中最常见的“程序闪退”等疑难杂症,帮助普通用户轻松完成微信取证。

m0n1o2p的博客 479

从网口变压器到TVS管:手把手设计通过4KV浪涌的以太网电路

本文详细解析工业级以太网接口4KV浪涌防护设计,从网口变压器选型到TVS管布局,提供通过IEC61000-4-5标准测试的完整方案。重点介绍Bob Smith电路优化和PCB设计技巧,帮助工程师有效应对雷电感应和设备开关瞬态干扰,确保工业设备稳定运行。

study的专栏 287

Dubbo 动态代理策略有哪些?

这些动态代理策略可以根据不同的需求和场景进行选择,以满足不同的性能和扩展性要求。Dubbo 还提供了丰富的配置选项,可以根据需要进行灵活的配置和调整。Dubbo 是一个高性能、轻量级的 Java RPC 框架,它支持多种动态代理策略。

qq_33240556的博客 965

DPO(Direct Preference Optimization)直接偏好优化

本文介绍了DPO(直接偏好优化)方法,该方法通过简化传统的RLHF(基于人类反馈的强化学习)流程,直接利用人类偏好数据进行模型优化。DPO的核心思想是跳过奖励模型训练和强化学习交互步骤,通过数学推导将优化目标转化为仅与策略概率分布相关的形式。推导表明最优策略与奖励模型之间存在显式关系,从而可以构建直接优化策略的损失函数。与RLHF相比,DPO简化了训练流程,提高了工程实现稳定性,同时保持了同等效果。

TeenLucifer的博客 1956

Dubbo之ProxyFactory

为什么80%的码农都做不了架构师?>>> ...

weixin_34072857的博客 550

【100%通过率】华为OD机试真题 C++ 实现【水库蓄水问题】【2022.11 Q4 新题】

给定一个长度为 n 的整数数组height。数组的元素表示山的高度,选择两个元素作为水库的边界,求蓄水量的最大值并输出蓄水量最大时的边界下标(蓄水量相同时输出下标较近的)。

MISAYAONE的博客 1万+

零基础基于U-Net网络实战眼底图像血管提取

文章目录1 前言2 血管提取任务概述3 U-Net架构简介4 眼底图像血管分割代码5 结果评估可视化(ROC曲线)6 改进U-Net网络完成眼底图像血管提取任务思路 1 前言 本文基于U-Net架构完成了视网膜血管的提取任务,基于Keras框架更简单的实现分割,网络、工具类、训练和预测的代码一目了然

NJU phd 在读。 5204

Dubbo服务调用过程

服务调用过程 由于 Invoker 是 Dubbo 领域模型中非常重要的一个概念,很多设计思路都是向它靠拢。这就使得 Invoker 渗透在整个实现代码里,对于刚开始接触 Dubbo 的人,确实容易给搞混了。 下面我们用一个精简的图来说明最重要的两种 Invoker——服务提供 Invoker 和服务消费 Invoker: 贴一张服务调用的整体过程图 这张图可以看出大致的整理流程,然而一些集群,重试,负载均衡等步骤会专门抽出一节来讲。本章更注重服务端和消费端具体的通信细节,线程模型等。 客户端调用 客

3289

DISK配置服务器软RAID工作任务(RAID1+BITLOCKER)-winserver4

DISK配置服务器软RAID工作任务(RAID1+BITLOCKER)-winserver4

新时代先锋的博客 7299

【Dubbo】Dubbo源码环境与开发环境搭建

本文实战与理论相结合,先讲解Dubbo开发环境搭建下载并安装JDK、Zookeeper、IDE、Maven等等,在讲解ubbo源码环境搭建的环境准备,如何下载源码、导入工程并代码调试,最后分析dubbo项目中的核心模块。

小明的Java问道之路 3663

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Dubbo底层源码解析

目录 1、Dubbo核心模块职责介绍 2、源码基础 2.1 SPI自适应 2.2 Netty实现简易Dubbo 3、标签解析 3.1 标签属性配置 3.2 配置渊源 4、服务暴露 4.1 服务暴露启动逻辑 4.2 参数检查 4.3 组装url 4.4 服务暴露分类 4.5 服务暴露 4.6 服务注册 5、服务发现 5.1 服务发现原理 5.2 服务引用入口 5.3 创建代理 5.4 代理调用 1、Dubbo核心模块职责介绍 Dubbo发展到现在,已经有3.0版.

长沙老码农 3945

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

[Dubbo3.0.8源码解析系列]-3-框架,应用程序,模块领域模型Model对象的初始化

3-ModuleModel对象的建模 在上一章中我们看到AbstractMethodConfig的构造器中有这么一行代码用来创建模块模型对象,那这一章我们就来看下模型对象的初始化过程: public AbstractMethodConfig() { super(ApplicationModel.defaultModel().getDefaultModule()); } 3.1 模块模型(ModuleModel)参数对象的创建 这个AbstractMethodConfig构.....

宋小生-中间件 3274

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Dubbo(七)系统架构解析(两大设计原则、三大领域模型、四大组件、十层架构图、Dubbo源码架构)

Dubbo的系统架构解析 1. Dubbo 的两大设计原则 Dubbo 框架在设计时遵循了两大设计原则: Dubbo 使用“微内核+插件”的设计模式。内核只负责组装插件(扩展点),Dubbo 的功能都是由插件实现的,也就是 Dubbo 的所有功能点都可被用户自定义扩展类所替换。 采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息。 URL:协议://IP地址:端口/服务名/各种元数据信息... 为什么dubbo用url不用json? 个人理解,dubbo的应用场景涉及各

语雀同名:犬豪 yuque.com/qhao 1951

Dubbo架构设计、服务注册与消费源码剖析

本文知识点较多,篇幅较长,请耐心学习 题记: 文章内容输出来源:拉勾教育Java高薪训练营。 本篇文章是 Dubbo 学习课程中的一部分笔记。 Dubbo架构设计和服务注册与消费源码剖析 一、源码下载和编译 源码下载、编译和导入步骤如下: (1)dubbo的项目在github中的地址为: https://github.com/apache/dubbo (2)进入需要进行下载的地址,执行 git clone https://github.com/apache/dubbo.git (3)为了防止master.

weixin_41018580的博客 3836

dubbo的源码架构

代码架构,将介绍 Dubbo 代码架构。

weixin_44550507的博客 192

Dubbo 3.x源码(6)—Dubbo3域模型以及Model和Environment初始化【一万字】

基于Dubbo 3.1,详细介绍了Dubbo 3域模型的概念以及Model和Environment初始化。

终生学习践行者 1561

Dubbo 3.x源码(4)—Dubbo SPI机制的源码【一万字】

基于Dubbo 3.1,详细介绍了Dubbo SPI机制的源码。

终生学习践行者 914

完整版来了:阿里Dubbo技术负责人准备的源码教程,很有大厂风格

在技术领域,不断学习和深入了解先进的技术是保持竞争力的关键。今天,我们迎来了一份备受期待的源码教程——阿里Dubbo技术负责人准备的完整版!这不仅仅是一份教程,更是一次近距离感受大厂技术风格的机会。标题中提到的阿里Dubbo技术负责人为我们准备的教程,无疑让人期待满满。大厂的技术负责人,通常代表着丰富的实战经验和深厚的技术底蕴。这份完整版的源码教程,或许会为广大技术爱好者和从业者带来前所未有的学习体验。这不仅是一次深入Dubbo框架的机会,更是一次近距离感受大厂技术风格的机遇。

m0_62051288的博客 1138

dubbo源码分析 之 服务暴露概述-6

dubbo的服务模型是非常简单的,要么是服务提供方(Provider)提供服务,要么是服务消费方(Consumer)消费服务,从dubbo官网的系统架构图就可以看出来。 Provider与Consumer通过Registry来解耦合,这一点和Spring有点相似。在Spring中它的核心领域模型是Bean.我们通过配置bean,然后Spring容器获取到需要的对象。不需要关心对象的创建过程...

Jack博客 291

Dubbo暴露服务和引用服务的实现源码分析

它分析该文件中的每一行(每一行对应一个类),分析这些类,如果发现有哪个类的Annotation是@Adaptive,则找到对应的AdaptiveClass了,但由于Protocol文件里没有哪个类的Annotation是@Adaptive,所以在这个例子中该方法没找到对应的AdaptiveClass。ExtensionLoader是Dubbo中一个非常重要的类,刚接触Dubbo源码的人看这个类的时候也多少会有点困惑,这个类非常重要,它就像是厨房里的“大厨”,按照用户的随时需要把各种“食材”烹调出来。

2401_89694015的博客 581

阿里巴巴Dubbo实现的源码分析

Dubbo是阿里巴巴开源出来的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及作为SOA服务治理的方案。它的核心功能包括: #remoting:远程通讯基础,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。 #Cluster: 服务框架核心,提供基于接口方法的远程过程调用,包括多协议支持,并提供软负载均衡和容错机制的集群支...

weixin_40341338的博客 1026

Dubbo框架的1个核心设计点

Java领域要说让我最服气的RPC框架当属Dubbo,原因有许多,但是最吸引我的还是它把远程调用这个事情设计得很有艺术。

程序员半支烟,wechat:yclxiao 592
上一篇: Dubbo源码(4)-Zookeeper注册中心源码解析
下一篇: Dubbo源码(6)-动态代理技术源码解析
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值