服务负载均衡-Dubbo篇

本文深入探讨了Dubbo的负载均衡机制,包括客户端模式的负载均衡和两种模式的区别。详细解析了轮询和随机两种策略的实现原理,轮询通过权重调整策略确保公平,而随机策略结合权重增加特定服务被选中的概率。Dubbo还提供了其他策略如一致性哈希和最小活跃数。了解这些策略有助于优化服务调用的效率和稳定性。
摘要由CSDN通过智能技术生成

关键词:负载均衡    轮询算法    随机算法


Dubbo源码版本:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.6.9</version>
</dependency>

负载均衡分为两种模式:客户端模式和服务端模式。客户端模式是服务消费者(调用方)从注册中心获取可用的服务列表,然后根据负载均衡算法选择一个服务进行调用,Dubbo中的负载均衡就是使用的客户端模式。服务端模式,是服务消费者直接调用一个服务,由该服务进行负载均衡,比如Nginx使用的是服务端模式。

一般在集群模式中,服务都是多个的。服务调用方与服务提供方一般都是多对多的关系。当一个服务调用方需要调用一个功能接口时,提供该功能接口的服务是多个,因此需要从这些服务提供者中选择一个服务进行调用。这样的过程就叫负载均衡。

负载均衡是有策略的,也就是从多个服务提供者中如何确定出一个用于本次的服务调用。这个如何确定的过程就是负载均衡策略,也叫负载均衡算法。一般有轮询、随机等。


█ 服务调用

详细的服务调用说明请戳《服务调用-Dubbo篇

通过上面的内容获取到了服务接口的代理对象,比如有这样一个接口:CatService:

public interface CatService {

    void say();

}

生成的代理对象就是这样的(伪代码):

public class CatServiceProxy implements CatService{

    @Override
    public void say() {
        // 逻辑会被转发到MockClusterInvoker的invoke方法中
        // invocation里面封装了接口、调用方法等信息
        mockClusterWrapper.invoke(invocation);

    }
}

MockClusterWrapper.invoke:

public Result invoke(Invocation invocation) throws RpcException {
    Result result = null;
    // mock功能,服务调用失败后的容错处理
    String value = this.directory.getUrl().getMethodParameter(invocation.getMethodName(), "mock", Boolean.FALSE.toString()).trim();
    // 使用了mock功能
    if (value.length() != 0 && !value.equalsIgnoreCase("false")) {
        if (value.startsWith("force")) {
            if (logger.isWarnEnabled()) {
                logger.info("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + this.directory.getUrl());
            }

            result = this.doMockInvoke(invocation, (RpcException)null);
        } else {
            try {
                result = this.invoker.invoke(invocation);
            } catch (RpcException var5) {
                if (var5.isBiz()) {
                    throw var5;
                }

                if (logger.isWarnEnabled()) {
                    logger.warn("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + this.directory.getUrl(), var5);
                }

                result = this.doMockInvoke(invocation, var5);
            }
        }
    } else {
        // 没有使用mock功能,直接调用this.invoker.invoke
        result = this.invoker.invoke(invocation);
    }

    return result;
}

this.invoker.invoke:

MockClusterWrapper中持有的是FailoverClusterInvoker,所以会调用FailoverClusterInvoker中的invoke方法,FailoverClusterInvoker继承了AbstractClusterInvoker,invoke是AbstractClusterInvoker中的方法:

public Result invoke(Invocation invocation) throws RpcException {
    ......
    LoadBalance loadbalance = null;
    ......
    // 获取服务列表
    List<Invoker<T>> invokers = this.list(invocation);
    // 获取LoadBalance,负载均衡器,可通过配置指定,默认为RandomLoadBalance
    if (invokers != null && !invokers.isEmpty()) {
        loadbalance = (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(((Invoker)invokers.get(0)).getUrl().getMethodParameter(RpcUtils.getMethodName(invocation), "loadbalance", "random"));
    }

    RpcUtils.attachInvocationIdIfAsync(this.getUrl(), invocation);
    return this.doInvoke(invocation, invokers, loadbalance);
}

this.doInvoke:

doInvoke是AbstractClusterInvoker定义的抽象方法,具体要看子类实现,进入FailoverClusterInvoker的doInvoke方法:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值