Dubbo学习之路(六):服务调用流程源码解读

本文深入探讨Dubbo的服务调用流程,从Director获取Invoker,经Router筛选有效Invoker,LoadBalance选择执行Invoker,到最后的Cluster容错处理。详细分析了Directort、Router、LoadBalance和Cluster的关键步骤,揭示了服务调用背后的逻辑。
摘要由CSDN通过智能技术生成

                                             服务调用流程源码解读     

我们先来看一下官网的集群容错图,也就是整体获取到执行的invker的过程

1.通过Directort获取到当前所有的Invoker

2.通过Router获取当前可执行的(有效的)所有Invoker

3.通过LoadBalance获取当前执行的单一Invoker

4.通过Cluster策略贯穿整个流程,进行容错处理

先看一段代码:

 @Autowired
    private DemoService demoServiceImpl;

    @GetMapping("/sayHello")
    @ApiOperation(value = "/sayHello",notes = "说你好")
    @ApiImplicitParam(name = "name",value = "名称",required = true,dataType = "String")
    public String sayHello(String name) {
        checkNotNull(name,"name is not null");
        return demoServiceImpl.sayHello(name);
    }

       这里的demoServiceImpl 是一个代理对象,这里有服务发现的东西,需要看我第五篇文章,

所以走到demoServiceImpl.sayHello(name),代码走的是动态代理模式。进入InvokerInvocationHandler.invoke()方法,在动态代理类里,我们发现有一个invoker字段:MockClusterInvoker对象

MockClusterInvoker.invoke()方法:判断是不是配置了MOCK请求,配置了走mock模式,没有配置接着进入:FailoverClusterInvoker.invoke(),FailoverClusterInvoker继承于AbstractClusterInvoker,所以我们进入AbstractClusterInvoker.invoke()方法。

public Result invoke(final Invocation invocation) throws RpcException {
        checkWhetherDestroyed();
        LoadBalance loadbalance = null;
        ① List<Invoker<T>> invokers = list(invocation);
        if (invokers != null && !invokers.isEmpty()) {
            ② loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
                    .getMethodParameter(invocation.getMethodName(), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
        }
        RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
        return ③ doInvoke(invocation, invokers, loadbalance);
    }

这个方法里我们可以看一下标注

①这里是获取到所有有效的可执行的Invoker

②获取负载均衡的处理方式

③通过负载规则拿到Invoker并执行返回

下面我们开始介筛第一步

protected List<Invoker<T>> list(Invocation invocation) throws RpcException {
        List<Invoker<T>> invokers = directory.list(invocation);
        return invokers;
    }

我们看到了Directort,这里调用的是 AbstractDirectory的list方法

public List<Invoker<T>> list(Invocation invocation) throws RpcException {
        if (destroyed) {
            throw new RpcException("Directory already destroyed .url: " + getUrl());
        }
        ① List<Invoker<T>> invokers = doList(invocation);
        List<Router> localRouters = this.routers; // local reference
        if (localRouters != null && !localRouters.isEmpty()) {
            for (Router router : localRouters) {
                try {
                    if (router.getUrl() == null || router.g
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值