dubbo服务暴露简版总结

2023-12-28 16:32

本文主要是介绍dubbo服务暴露简版总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

dubbo服务导出
1.serviceBean实现了ApplicationListener接口,当spring刷新上下文的时候,会回调onApplicationevent事件
2.是否延迟导出,执行export方法
3.执行父类ServiceConfig的export方法,
4.执行doExport
5.执行doExportUrl导出服务
6.执行doExportUrlForProtocol为每个协议下面导出服务
7.执行RegisteyProtocol里面的export方法,将服务者链接包装成invoker,并包装为exporter注册到注册中心,同时启动nettyServer进行端口监听

dubbo服务导入
1.饿汉式 referenceBean实现了initBean接口,当初始化bean的时候,执行afterPropertiesSet,进行服务引用
2.懒汉式 实现了FactoryBean接口,当spring加载自定义扩展bean的时候,调用getObjects方法,进行服务引入。默认为这种方式
3.调用父类referenceConfig的init方法进行初始化导出,
4.创建proxy,合并多个invoker
5.调用RegistryProtocol的refer ->doRefer向注册中心订阅服务,并获取invoker列表 通过cluster将多个invoker合并为一个invoker,将invoker转换为接口代理 同时启动nettyClient进行通讯


调用过程
1.消费者通过路由,智能容错,负载均衡确定某一个invoker,通过nettyclient进行编码,序列化并发送请求
2.服务者服务器接收到请求后,将数据分发到线程池,进行解码,执行invoke方法,并调用相应的代理类执行具体的接口方法


ioc
dubbo的ioc,是目标实例,类上没有注释@Adapative,并且有set方法,并且set方法只有一个参数,从工厂里面获取对象 并通过反射调用实例的set方法进行参数注入

aop
类上没有注释@Adapative 构造方法只有一个接口类型的参数,通过反射创建instance的一个代理类

 

 

 

对于接口方法,我们可以按照需求标注 Adaptive 注解。
在获取实现类的过程中,如果某个实现类被 Adaptive 注解修饰了,那么该类就会被赋值给 cachedAdaptiveClass 变量。
以 Protocol 接口为例,该接口的 destroy 和 getDefaultPort 未标注 Adaptive 注解,其他方法均标注了 Adaptive 注解。
Dubbo 不会为没有标注 Adaptive 注解的方法生成代理逻辑,对于该种类型的方法,仅会生成一句抛出异常的代码。


RegistryService的Registry ->AbstractRegistry的subscribe方法

FailbackRegistry的构造方法调用父类的构造方法,加载本地文件,同时调用自己的retry方法  zookeeperRegistry的doSubscribe方法调用父类FailbackRegistry的notify方法,执行super.notify(),执行父类 abstractRegistry中的notify.
将变化的url保存在缓存中,保存进properties,通过properties保存进file文件
调用RegistryDirectory 中的notify方法,执行refreshInvokers刷新本地缓存的服务者地址()
调用listener的notify方法  执行子类的RegistryDirectory的notify方法->执行refreshInvoker方法,刷新服务者本地缓存,并删除不可用的服务者信息


本地调用 则生成injvmInvoker 代理
远程调用
    1.如果配置了服务者地址,则表示直连,则将地址放进map
    2.则加载注册额中心地址,并放进map 
        2.对上面的map里面的信息创建dubboInvoker(直连情况下)
        2.如果注册中心链接不为空 非直连情况,则需要使用cluster将创建的所有invoker进行合并
创建proxy代理类        

DubboProtocol 创建inviker时候
public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
    optimizeSerialization(url);
    // 创建 DubboInvoker
    DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
    invokers.add(invoker);
    return invoker;
}
调用了getClients生成ExchangeClient客户端

RegistryProtocol中的doRefer方法具体进行注册zk(订阅 providers、configurators、routers 等节点数据),同时获取服务者子节点信息,放进urls中 进行处理


导出服务
ServiceBean实现了ApplicationListener接口,在spring刷新上下文时候会回调onApplicationEvent方法,进行服务导出
    ServiceBean#onApplicationEvent事件,export方法(父类方法),
    -->ServiceConfig#export方法:是否延迟加载,如果延迟则放进延迟线程池延迟执行导出任务,否则调用导出
        -->ServiceConfig#doExport:数据参数校验
            -->ServiceConfig#doExportUrls:获取注册中心地址,为每个地址导出在各种协议下导出服务,
                1.doExportUrls:获取配置文件中的注册中心地址
                2.doExportUrlsFor1Protocol:填充信息,默认导出到本地和远程,加载监视器链接地址,生成对应的exporter
                -->DubboProtocol#export:启动服务器server
                -->RegistryProtocol#export:导出服务到远程,进行注册中心注册
                
导入服务                
ReferenceBean实现了FactoryBean,InitializingBean接口
1.第一种饿汉式:在spring调用接口InitializingBean初始化Bean调用afterPropertiesSet时候,引用服务                    
2.第一种懒汉式:在spring调用FactoryBean扩展自定义类型的Bean时候调用getObject时候,引用服务,默认第二种,当我们的服务被注入到其他类中时,Spring 会第一时间调用 getObject 方法,并由该方法执行服务引用逻辑
-->ReferenceBean#getObject()当服务被注入到其他类的时候spring调用getObjects        
    -->ReferenceConfig#get()状态判断            
        -->ReferenceConfig#init()进行初始化处理,参数校验,填充            
            -->ReferenceConfig#createProxy创建代理并合并消费者invoker
                1.RegistryProtocol#refer获取注册中心地址并进行分组处理
                2.DubboProtocol#refer创建底层为netty的通讯客户端client
                -->RegistryProtocol#doRefer向注册中心注册服务,并订阅服务,将多个服务者进行合并
                
            
集群部署
FailOverClusterInvoker 在调用失败时,会自动切换 Invoker 进行重试   doInvoke 方法首先是获取重试次数,然后根 据重试次数进行循环调用,失败后进行重试。在 for 循环内,首先是通过负载 均衡组件选择一个 Invoker,然后再通过这个 Invoker 的 invoke 方法进行远程 调用。如果失败了,记录下异常,并进行重试。重试时会再次调用父类的 list 方 法列举 Invoker
FailbackClusterInvoker 会在调用失败后,返回一个空结果给服务消费者。并通 过定时任务对失败的调用进行重传,适合执行消息通知等操作。
FailfastClusterInvoker 只会进行一次调用,失败后立即抛出异常。适用于幂等操 作,比如新增记录
FailsafeClusterInvoker 是一种失败安全的 Cluster Invoker。所谓的失败安全是 指,当调用过程中出现异常时,FailsafeClusterInvoker 仅会打印异常,而不会抛 出异常。适用于写入审计日志等操作。            
Forking Cluster 并行调用,只要有成功就返回
Broadcast Cluster 广播调用所有的服务者,只要有一个失败就返回            
            
            
负载均衡            
负载均衡所有的负载均衡方法都继承自AbstractLoadBalance,该类实现LoadBalance接口,并封装了一些公共的逻辑
    1,如果只有一个invoker直接返回,
    2.多余一个则根据时间(需要的启动时间和已经启动的时间)判断机器是否部署完成,进行重新计算权重    
默认是RandomLoadBalance加权随机算法
-->doSelect获取所有invoker的加权数总和,默认加权数相等状态设置为true,只要有加权数与上一个不相等,则设置为false,
    取从0-总权重数之间取一个随机总数,循环遍历所有的invoker的权重进行相减,当小于0时候,则返回当前的invoker
LeastActiveLoadBalance最小活跃数负载均衡
    1.初始的活跃值都为0.收到一个请求,活跃值+1,处理完一个请求活跃值-1,性能高的机器,活跃值越小
-->doSelect    记录最小活跃数invoker的下标和权重总数,如果最后的总量只有1,则直接返回,
            否则,取0-总权重之间一个随机数,循环这些invoker,总量的权重-当前invoker的权重,如果小于0,则返回当前invoker
ConsistentHashLoadBalance一致性 hash 算法
-->doSelect 它的工作过程是这样的,首先根 据 ip 或者其他的信息为缓存节点生成一个 hash,并将这个 hash 投射到 [0, 2^32 - 1] 的圆环上。当有查询或写入请求时,则为缓存项的 key 生成一个 hash 值。然后查找第一个大于或等于该 hash 值的缓存节点,并到这个节点中查询或 写入缓存项。如果当前节点挂了,则在下一次查询或写入缓存时,为缓存项查找 另一个大于其 hash 值的缓存节点即可
RoundRobinLoadBalance加权轮询    在轮询过程中进行重新加权重,以调控每台机器的负载

                
//服务调用过程
InvokerInvocationHandler invoke方法  拦截object中的方法
  -->MockClusterInvoker  invoke方法  是否配置force,判断是否执行mock逻辑,或者调用远程
      —> AbstractClusterInvoker#invoke(Invocation)  数据校验,创建负载均衡实例
        —> FailoverClusterInvoker#doInvoke(Invocation, List<Invoker<T>>, LoadBalance)
          —> Filter#invoke(Invoker, Invocation)  // 包含多个 Filter 调用
            —> ListenerInvokerWrapper#invoke(Invocation) 
            -->AbstractInvoker invoke方法设置invocation的参数(path,attachment),
              -->DubboInvoker  doInvoke  ExchangeClient客户端(在注册消费者时候创建的客户端)调用发送请求(异步无返回(返回空的RpcResult),异步又返回(暂时返回空的RpcResult),同步调用(get方法需等待DefaultFuture实现))
                -->ReferenceCountExchangeClient request(Object request, int timeout)    调用send接口 由HeaderExchangeClient实现
                    -->HeaderExchangeClient request(Object request, int timeout) 返回ResponseFuture
                      -->HeaderExchangeChannel  request(Object request, int timeout)创建Request对象
                        -->NettyClient  send方法(父类AbstractPeer的实现)
                          --> AbstractClient send(Object message, boolean sent)  获取到channel
                            -->    NettyChannel send(Object message, boolean sent) 发送消息
                             --> NioClientSocketChannel#write(Object)  写数据信息        
                     
                     

            //接收到调用请求处理过程
            解码器将数据包解析成 Request 对象后    NettyHandler 的 messageReceived 方法紧接着会收到这个对象,并将这个对象继续向下传递
                NettyHandler#messageReceived(ChannelHandlerContext, MessageEvent) 获取NettyChannel实例,
                  —> AbstractPeer#received(Channel, Object) 是否关闭校验
                    —> MultiMessageHandler#received(Channel channel, Object message)  按照message进行处理(MultiMessage类型的,则遍历调用,否则直接调用)
                      —> HeartbeatHandler#received(Channel, Object)  心跳递增,并设置Attribute,并创建Response
                        —> AllChannelHandler#received(Channel, Object)  将数据分发到线程池
                          —> ExecutorService#execute(Runnable)    // 由线程池执行后续的调用逻辑
                            -->DecodeHandler received对接收到的数据进行解码
                              -->HeaderExchangeHandler received(Channel channel, Object message)  处理事件转换对象
                                   -->DubboProtocol    received接收到请求        
                                      -->DubboProtocol reply方法根据Invocation获取invoker实例,执行invoke方法,
                                        -->AbstractProxyInvoker invoke(Invocation invocation) // 调用 doInvoke(子类JavassistProxyFactory实现) 执行后续的调用,并将调用结果封装到 RpcResult 中,
                                            Wrapper 是一个抽象类,其中 invokeMethod 是一个抽象方法。Dubbo 会在运行时通过 Javassist 框架为 Wrapper 生成实现类,并实现 invokeMethod 方法,该方法最终会根据调用信息调用具体的服务
                                            -->JavassistProxyFactory doInvoke(T proxy, String methodName,Class<?>[] parameterTypes,Object[] arguments)方法,调用具体的wrapper.invokeMethod()
 

这篇关于dubbo服务暴露简版总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/546562

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果