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()
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值