dubbo源码分析-consumer端4-ClusterInvoker与LoadBalance

        dubbo中提供了多种集群调用策略:

        1、FailbackClusterInvoker :  失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作;

        2、FailfastClusterInvoker: 快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作;

        3、FailoverClusterInvoker: 失败转移,当出现失败,重试其它服务器,通常用于读操作,但重试会带来更长延迟;

        4、FailsafeClusterInvoker: 失败安全,出现异常时,直接忽略,通常用于写入审计日志等操作;

        5、FokingClusterInvoker: 并行调用,只要一个成功即返回,通常用于实时性要求较高的操作,但需要浪费更多服务资源;

        6、MergeableClusterInvoker:合并多个组的返回数据;

        开发者可以根据实际情况选择合适的策略,这里我们选择FailoverClusterInvoker(官方推荐)进行讲解,通过它来了解集群调用处理的问题,了解它以后其他的策略也很容易了。

        由多个相同服务共同组成的一套服务,通过分布式的部署,达到服务的高可用,这就是集群。与单机的服务不同的是,我们至少需要:1、地址服务(Directory);2、负载均衡(LoadBalance)。  地址服务用于地址的管理,如缓存地址、服务上下线的处理、对外提供地址列表等,通过地址服务,我们可以知道所有可用服务的地址信息。负载均衡,则是通过一定的算法将压力分摊到各个服务上。 好了,知道这两个概念后,我们开始正式的代码阅读。

        当应用需要调用服务时,会通过invoke方法发起调用(AbstractClusterInvoker):

    public Result invoke(final Invocation invocation) throws RpcException {
        // 是否被销毁
        checkWheatherDestoried();

        LoadBalance loadbalance;
        // 通过地址服务获取所有可用的地址信息
        List<Invoker<T>> invokers = list(invocation);
       
        if (invokers != null && invokers.size() > 0) {
            // 如果存在地址信息,则根据地址中的配置加载LoadBalance,注意负责均衡策略配置的优先级 privider > consumer            
           loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
                    .getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
        } else {
            // 如果暂时没有地址信息,则使用默认的负载均衡策略策略(random)
           loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
        }
        // 如果是异步的话需要加入相应的信息
        RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
        // 根据地址及负载均衡策略发起调用
        return doInvoke(invocation, invokers, loadbalance);
    }

    protected  List<Invoker<T>> list(Invocation invocation) throws RpcException {
     List<Invoker<T>> invokers = directory.list(invocation);
     return invokers;
   }
        doInvoke则是各个子类来实现,以FailoverClusterInvoker为例:

    public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
    	List<Invoker<T>> copyinvokers = invokers;
        // 检查地址列表是否正确(需要确保有可用的地址)
    	checkInvokers(copyinvokers, invocation);
        // 从retries参数获取重试的次数,如retries=3,则最大可能调用的次数为4
        // 需要注意的是默认的重试次数为2(及最多执行3次),对于一些写服务来说,如果无法做到幂等,最好是将retries参数设为0,或者使用failfast策略
        int len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + 1;
        if (len <= 0) {
            len = 1;
        }
        // retry loop.
        RpcException le = null; // last exception.
        List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyinvokers.size()); // invoked invokers.
        Set<String> providers = new HashSet<String>(len);
        // 发起指定次数的调用,一旦其中一次成功则返回
        for (int i = 0; i < len; i++) {
        	//重试时,进行重新选择,避免重试时invoker列表已发生变化.
        	//注意:如果列表发生了变化,那么invoked判断会失效,
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值