Dubbo服务引用

官网

客户端服务引用

客户端服务引用 demo

DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
demoService.sayHello("world");

dubbo 在客户端动态的生成了一个该 Interface 类型的代理类.在这个代理类中封装了远程服务调用的组件.

DemoService 创建

<dubbo:reference id="demoService" group="g1" check="true" interface="com.alibaba.dubbo.demo.DemoService"
                     client="netty4" timeout="10000" callbacks="1000" registry="zk01" filter="demo2">

Spring 容器启动时,AbstractBeanFactory.isFactoryBean() 会判断 demoService 配置的 RootBeanDefinition 的 beanType 为com.alibaba.dubbo.config.spring.ReferenceBean,它是个 FactoryBean,Spring 容器会创建 ReferenceBean 这个 FactoryBean 实例.

获取 DemoService

DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy

会调用 factoryBean.getObject() 方法,即调用 ReferenceBean.getObject() 创建 demoService 实例.

DUBBO-issue-2757 debug 时候遇到这个 bug 了,需要在 idea 里设置下.

在服务提供方,Invoker 用于调用服务提供类.在服务消费方,Invoker 用于执行远程调用.

客户端服务引用流程

- refer
- context.getBean("demoService")
    - ReferenceBean.getObject():通过这个 FactoryBean 创建 demoService 实例
        - ReferenceConfig.init(): 调用父类ReferenceConfig.init()
            - ReferenceConfig.createProxy(map)创建DemoService代理对象
            - 1.远程引用的逻辑
            - 1.1.loadRegistries()加载注册中心URL数组
            - 1.2.引用服务invoker = refprotocol.refer(interfaceClass, urls.get(0))
                - Protocol$Adaptive.refer()
                    - ProtocolFilterWrapper.refer()
                        - ProtocolListenerWrapper.refer()
                            - RegistryProtocol.refer()
                            - 1.获取注册中心的url
                            - 2.获得注册中心registryFactory.getRegistry(url)
                            - 3.执行服务引用doRefer(cluster, registry, type, url)
                                - RegistryProtocol.doRefer()
                                - 1.根据DemoService的type和url创建RegistryDirectory 对象,并设置注册中心
                                - 2.向注册中心注册自己(服务消费者)registry.register()
                                - 3.向注册中心订阅 服务提供者 + 路由规则 + 配置规则
                                - 4.通过cluster创建Invoker对象cluster.join(directory)并返回Invoker
            - 1.3.生成invoker的代理对象并返回 return (T) proxyFactory.getProxy(invoker)
                - ProxyFactory$Adaptive().getProxy()
                    - JavassistProxyFactory.getProxy(invoker, interfaces)
                        - Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker))
                            - new InvokerInvocationHandler(invoker) // invoker为MockClusterInvoker实例

客户端服务调用

demoService.sayHello(“world”)

- consumer-call
- demoService.sayHello("world")
    - com.alibaba.dubbo.common.bytecode.proxy0.sayHello(name) // 服务代理类
        - InvokerInvocationHandler.invoke(proxy, method, args)
        - 1.获取参数名和方法名
        - 2.RPC调用invoker.invoke(new RpcInvocation(method, args)).recreate()
            - 1.将method和参数封装成RpcInvocation对象
            - 2.MockClusterInvoker.invoke(invocation)
                - result = this.invoker.invoke(invocation)调用FailoverClusterInvoker.invoke(),先走父类AbstractClusterInvoker.invoke()
                    - 1.通过 directory 获得所有服务提供者 Invoker 集合RegistryDirectory.list(Invocation invocation)
                        - AbstractClusterInvoker.list(invocation)
                            - 1.AbstractDirectory.list(invocation)
                                - RegistryDirectory.doList(invocation)
                                - 1.从localMethodInvokerMap中根据methodName获取所有匹配的invokers
                            - 2.根据routers,调用router.route()筛选invokers
                                - MockInvokersSelector.route()
                                    - 对于普通invoker集合,调用MockInvokersSelector.getNormalInvokers(invokers)
                                        - 不包含 MockInvoker 的情况下,直接返回 `invokers` 集合
                            - 3.获取loadBalance,默认是RandomLoadBalance实例
                            - 4.doInvoke(invocation, invokers, loadbalance)执行调用
                                - FailoverClusterInvoker.doInvoke()中
                                - 1.获取最大可调用次数: 最大可重试次数 + 1
                                - 2.select(loadbalance, invocation, copyinvokers, invoked)根据负载均衡机制从 copyinvokers 中选择一个Invoker
                                    - AbstractClusterInvoker.doselect()
                                    - 1.若只有一个invoker直接选择
                                    - 2.如果只有两个Invoker,轮循取
                                    - 3.其余loadbalance.select(invokers, getUrl(), invocation)使用loadbalance获取invoker对象
                                        - // doSelect()具体的loadbalance算法实现
                                - 3.将选中的invoker添加到invoked(保存已经调用过的invokers)中,并设置到context里
                                - 4.发起RPC调用并返回result,invoker.invoke(invocation)
                                    - invokerWrapper.invoke(invocation)
                                        - ProtocolFilterWrapper$1.invoke()后面会调用filter链
                            - 5.调用成功就直接返回result了,失败则根据重试次数和策略重新选中invoker调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FlyingZCC

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

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

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

打赏作者

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

抵扣说明:

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

余额充值