dubbo源码实践-protocol层-invoker理解

news2025/6/28 0:46:47

1概述

Invoker官方解释:

Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实
现,也可能是一个远程的实现,也可能一个集群实现。

1.1 Invoker接口

通过源码可知Invoker接口不是SPI。 可以调用invoke方法执行调用。

Invocation是参数,如:调用那个方法名称、参数的类型、参数的值是什么等信息。

1.2 Invoker的实现类

从下图展示了各个Invoker实现类的作用。

2 例子代码

2.1 调用本地的实现

想象一下应用场景:dubbo服务提供者会先把提供的功能封装到service中,然后配置到dubbo中(注解或xml文件),dubbo就可以调用到这些service了。

问题:各个service的名称和方法都不同、参数也不一致,能用一种通用的方式掉用各个service吗?

解决方法:dubbo使用Invoker本地的实现来解决这个问题。

dubbo提供了两种实现方式JdkProxyFactory和JavassistProxyFactory。

2.1.1 JdkProxyFactory实现方式

InvokerTest类代码

package org.example.dubbo.invoker;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory;
import org.example.test.protocol.AlfService;
import org.example.test.protocol.IAlfService;
/** 本地Invoker使用, 2022/12/29. */
public class InvokerTest {
    public static void main(String[] args) {
        //业务服务类
        AlfService alfService = new AlfService();
        //构造一个空的url
        URLBuilder urlBuilder = new URLBuilder();
        URL url = urlBuilder.build();
        //构造Invocation对象
        RpcInvocation rpcInvocation = new RpcInvocation();
        rpcInvocation.setMethodName("sayHolle");//指定调用的方法名
        Class<?>[] parameterTypes = new Class[1];//指定调用的方法的参数类型
        parameterTypes[0] = String.class;
        rpcInvocation.setParameterTypes(parameterTypes);
        Object[] args1 = new Object[1];//指定调用的方法的参数
        args1[0] = "alf";
        rpcInvocation.setArguments(args1);
        //创建ProxyFactory
        ProxyFactory proxyFactory = new JdkProxyFactory();
        //传入service实例,接口和URL获取Invoker实例
        Invoker<IAlfService> invoker = proxyFactory.getInvoker(alfService, IAlfService.class, url);
        //调用invoker实例
        Result result = invoker.invoke(rpcInvocation);
        //获取service方法返回值
        Object value = result.getValue();
        System.out.println(value);

    }
}

AlfService类

package org.example.test.protocol;

/** 业务类 */
public class AlfService implements IAlfService{
    @Override
    public String sayHolle(String hi) {
        System.out.println("AlfService call");
        return "hi " + hi;
    }
}

运行结果,调用了service。

实现原理分析

不管什么service,通过proxyFactory.getInvoker获取到响应的Invoker实例,然后使用统一的invoke(Invocation invocation)方法来调用service。

JdkProxyFactory中的实现方式是通过java的反射实现的上述功能。

2.1.2 JavassistProxyFactory实现方式

只要把上面的代码替换成ProxyFactory proxyFactory = new JavassistProxyFactory(); 即可。

运行结果是一样的。

可以知道方式是通过javassist动态产生的一个Wrapper类的实现,然后编译、加载到JVM中。

产生的Wrapper实现的invokeMethod方法如下:

dubbo的默认实现是JavassistProxyFactory。因为性能更好。

2.2 远程调用

必须得有服务端才运行。这里就不演示了。参考DubboInvoker类实现。

下一篇会有例子。

2.3 集群的调用

集群的Invoker的继承关系如下图。

通过ClusterInvoker类的注释可以看到:

This is the final Invoker type referenced by the RPC proxy on Consumer side.
客户端使用该ClusterInvoker,并且是最外层的Invoker。

A ClusterInvoker holds a group of normal invokers, stored in a Directory, mapping to one Registry.
一个ClusterInvoker通过Directory持有一组普通的Invoker,Directory同时会对应一个注册(参考RegistryDirectory类)。

The ClusterInvoker implementation usually provides LB or HA policies, like FailoverClusterInvoker.
ClusterInvoker提供LB或者HA的功能,如FailoverClusterInvoker类。

In multi-registry subscription scenario, the final ClusterInvoker will referr to several sub ClusterInvokers, with each sub ClusterInvoker representing one Registry. Take ZoneAwareClusterInvoker as an example, it is specially customized for multi-registry use cases: first, pick up one ClusterInvoker, then do LB inside the chose Cluster。
在多注册中心订阅的场景下,一个最外层ClusterInvoker内部可以包含多个子ClusterInvoker,每个子ClusterInvoker代表的一个注册中心。可以参考ZoneAwareClusterInvoker类。

具体的例子请见下一篇文章。

2.4 AsyncToSyncInvoker类异步转同步

This class will work as a wrapper wrapping outside of each protocol invoker.
一个包装类,套在protocol invoker外面。

客户端调用服务端代码时应该是异步的(通过protocol invoker调用的),客户端可以在这个protocol invoker外面套一个AsyncToSyncInvoker,这样就转换到同步了,简化了代码的开发。

3 官方架构图中的Invoker

最开始看这张架构图,对里面3处Invoker不是很理解,现在终于清楚了。

1处:处理集群的Invoker,对外是一个Invoker,内部使用负载均衡等方法来选择一个Invoker(调用远程服务)来调用。

2 处:调用远程的Invoker。

3 处:服务端包装业务service的Invoker。

其实dubbo是一个RPC框架,要解决的就是客户端程序调用服务端程序。

服务端:用Invoker来封装业务service;

客户端:用Invoker来封装远程调用,用Invoker来封装集群。

顺便感叹一下,这个架构图画的真牛!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 机器学习最常打交道的 27 款工具包

为了大家能够对人工智能常用的 Python 库有一个初步的了解&#xff0c;以选择能够满足自己需求的库进行学习&#xff0c;对目前较为常见的人工智能库进行简要全面的介绍。 1、Numpy NumPy(Numerical Python)是 Python的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算…

Maix Bit(K210)保姆级入门上手教程

Maix Bit&#xff08;K210&#xff09;快速上手 这是K210快速上手系列文章&#xff0c;主要内容是&#xff0c;设备连接&#xff0c;环境准备&#xff0c;运行第一个程序 阅读文章前提&#xff1a;python基础,K210是使用Micropython脚本语法的&#xff0c;因此需要一些python…

RocketMQ5.0.0部署与实例

一、Idea调试1.相关配置文件在E:\rocketmq创建conf、logs、store三个文件夹。从RocketMQ distribution部署目录中将broker.conf、logback_namesrv.xml、logback_broker.xml文件复制到conf目录。如下图所示。其中logback_namesrv.xml、logback_broker.xml分别是NameServer、Brok…

纯C语言实现动态爱心(详解,初学者也能看懂)

文章目录✍动态爱心实现&#x1f496;一段小故事&#xff1a;爱心函数的由来&#x1f388; 创建动态爱心的准备&#xff08;非小白可以跳过&#xff09;1.爱心字符2.对easyx库里面的基础函数的认识①initgraph函数②settextcolor、settextstyle、setbkmode、outtextxy四种函数③…

PostgresSQL数据库的使用

PostgresSQL数据库的使用 下载安装 数据类型 使用指导 数据库操作 连接控制台 psql -h <实例连接地址> -U <用户名> -p <端口号>参数描述实例连接地址RDS PostgreSQL实例的连接地址&#xff0c;本机可用localhost或者127.0.0.1用户名创建的RDS Postgre…

ES语法扩展

剩余参数 剩余参数本质 // 剩余参数的本质const add(x,y,...args)>{console.log(x,y,args);}add();add(1);add(1,2);add(1,2,3,4,5); 剩余参数的注意事项 箭头函数的参数部分即使只有一个剩余参数&#xff0c;也不能省略圆括号使用剩余参数替代arguments获取实际参数剩余…

4.Isaac Jetson Nano 入门

Isaac Jetson Nano 入门 本节介绍如何在 Jetson Nano 设备上运行 Isaac SDK 示例应用程序。 有关如何开始使用 Nano 的一般说明&#xff0c;请参阅 Jetson Nano 开发工具包入门。 文章目录Isaac Jetson Nano 入门获取 IP 地址在 Jetson Nano 上运行示例应用程序PingOpenCV 边缘…

Pytorch CIFAR10图像分类 EfficientNet v1篇

Pytorch CIFAR10图像分类 EfficientNet v1篇 文章目录Pytorch CIFAR10图像分类 EfficientNet v1篇4. 定义网络&#xff08;EfficientNet&#xff09;EfficientNet介绍EfficientNet性能比较EfficientNet的baselineEfficientNet模型混合缩放方法其他版本的EfficientNet(B1-B7)判断…

错题 3jxn (8253复杂)

A 指示型指令 C 比如 ,跟C语言的return 一样&#xff0c;可以由多条&#xff0c;但是返回的位置都是一个地方 JN NEXT RET NEXT: RET A 可以重复 EQU不可以重复 C 中断向量&#xff1a;中断服务程序的入口地址 向量中断&#xff1a;识别中断你的方法 接口 编程题&#xff…

Redis关键知识点总结

Reference: http://redis.cn用处缓存数据库分布式锁&#xff08;Redission的redlock&#xff0c;自定义的lock等&#xff09;过滤器&#xff08;布隆过滤器/增强的带计数的布隆过滤器/布谷鸟过滤器等&#xff09;大规模的计算辅助&#xff08;bitmap&#xff09;消息订阅/监听 …

PyQt5入门学习(一)【小白入门系列】

PyQt5入门学习 介绍&#xff1a;PyQt5是Python较好的图形库&#xff0c;与C的Qt不同的是PyQt5封装得较为简单&#xff0c;上手也更加的方便。下面话不多说&#xff0c;开始学习PyQt5吧&#xff01; 安装过程 安装方法有两种&#xff0c;一种是下载PyQt5最新源码进行编译安装…

初识Kafka

1.1 定义 Kafka传统定义: Kafka是一个分布式的基于发布/订阅模式的消息队列(MessageQueue&#xff09;&#xff0c;主要应用于大数据实时处理领域。 发布/订阅: 消息的发布者不会将消息直接发送给特定的订阅者&#xff0c;而是将发布的消息分为不同的类别&#xff0c;订阅者只…

[数据结构基础]二叉树——堆的概念、结构、接口函数及经典的Topk问题和堆排序问题

目录 一. 堆的概念及结构 1.1 堆的概念 1.2 堆的结构及在内存中的存储 二. 堆的主要接口函数 2.1 堆初始化函数HeapInit 2.2 堆销毁函数HeapDestroy 2.3 向堆中插入数据函数HeapPush&#xff08;以小堆为例&#xff09; 2.4 删除堆根节点数据函数HeapPop&#xff08;小…

C++ 夺冠!成为 TIOBE 2022 年度编程语言

目录&#xff1a;C夺冠—成为TIOBE2022年度编程语言一、前言二、C 摘得桂冠三、Top 10 编程语言 TIOBE 指数走势&#xff08;2002-2023&#xff09;四、历史排名&#xff08;1987-2023&#xff09;五、编程语言“名人榜”&#xff08;2003-2022&#xff09;六、说明一、前言 2…

vitepress(三):自动生成目录

上一节我们将自己的网站发布到了git pages上&#xff0c;但是现在我们需要每次更新一篇文章就重写一次目录&#xff0c;操作上十分的繁琐和不方便&#xff0c;所以我们需要一个方法去自动生成我们的侧边栏结构&#xff0c;方便我们每次只需要更新我们的项目即可。这里我们要知道…

【每日一题】【LeetCode】【第六天】【Python实现】加一

加一的解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 1这个很好理解&#xff0c;唯一的难点就是个位1导致的进位的问题&#xff0c;可能会只会导致十位1&#xff0c;也有像8999这样产生多次进位的情况。 为了解决进位问题&#xff0c;自己想到了第三天学…

mysql三表查询15个例子带你搞懂它

mysql三表查询30个经典案例创建三个表a、b、c表a中的数据表b中的数据表c中的数据1.查询出学习成绩70分以上的学生姓名与成绩与学科&#xff1b;2.查询姓名以mi结尾的学生姓名及其任课老师姓名&#xff1b;3.选修课名为math的学生学号与姓名;4.选修课号为C4的学生学号&#xff1…

QEMU调试Linux内核环境搭建

一个最小可运行Linux操作系统需要内核镜像bzImage和rootfs&#xff0c;本文整理了其制作、安装过程&#xff0c;调试命令&#xff0c;以及如何添加共享磁盘。编译内核源码从 The Linux Kernel Archives 网站下载内核源码&#xff0c;本文下载的版本为4.14.191&#xff0c;4.14.…

危险程度(并查集)

有 nn 种化学物质&#xff0c;编号 1∼n1∼n。 其中&#xff0c;有 mm 对物质之间会发生反应。 现在&#xff0c;要将这些化学物质逐个倒入同一个试管之中&#xff0c;具体倒入顺序不限。 我们需要计算一下试管的危险值。 已知&#xff0c;空试管的危险值为 11&#xff0c;…

【UE4 第一人称射击游戏】21-添加动态扩散准心

素材资料地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1epyD62jpOZg-o4NjWEjiyg密码&#xff1a;jlhr上一篇&#xff1a;【UE4 第一人称射击游戏】20-添加瞄准十字线本篇效果&#xff1a;步骤&#xff1a;将资源移至FPS项目文件夹内移入后发现多了一个名为“WBCro…