zoukankan      html  css  js  c++  java
  • dubbo负载均衡与集群集群容错

    1.负载均衡

       在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。

    1.  负载均衡策略

    • Random LoadBalance

    随机,按权重设置随机概率。(默认值)
    在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

    • RoundRobin LoadBalance

    轮询,按公约后的权重设置轮询比率。(按权重分配)
    存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

    • LeastActive LoadBalance

    最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
    使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

    • ConsistentHash LoadBalance

    一致性 Hash,相同参数的请求总是发到同一提供者。
    当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
    算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
    缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />
    缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />

    2.  配置

    服务端服务级别

    <dubbo:service interface="..." loadbalance="roundrobin" />

    客户端服务级别

    <dubbo:reference interface="..." loadbalance="roundrobin" />

    服务端方法级别

    <dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
    </dubbo:service>

    客户端方法级别

    <dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
    </dubbo:reference>

    3.负载均衡测试

    (1)服务接口

    package dubbo;
    
    public interface DubboService {
        String sayHello(String name);
    }

    (2)两个实现类

    package dubbo;
    
    public class DubboServiceImpl implements DubboService {
        public String sayHello(String name) {
            return "Hello " + name;
        }
    }
    package dubbo;
    
    public class DubboServiceImpl2 implements DubboService {
        public String sayHello(String name) {
            return "Hello " + name + ",DubboServiceImpl2";
        }
    }

    (3)dubbo服务生产者 provider.xml

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="hello-world-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
            <dubbo:parameter key="qos.accept.foreign.ip" value="true" />
            <dubbo:parameter key="qos.port" value="2222" />
        </dubbo:application>
    
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="dubbo.DubboService" ref="demoService" />
        <dubbo:service interface="dubbo.DubboService" ref="demoService2" />
        <!-- 和本地bean一样实现服务 -->
        <bean id="demoService" class="dubbo.DubboServiceImpl" />
        <bean id="demoService2" class="dubbo.DubboServiceImpl2" />
    </beans>

    生产者代码:

    package dubbo;
    
    import java.io.IOException;
    import java.util.concurrent.CountDownLatch;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Provider {
        public static void main(String[] args) throws IOException, InterruptedException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "provider.xml" });
            context.start();
    
            CountDownLatch countDownLatch = new CountDownLatch(1);
            countDownLatch.await();
        }
    }

    (4)消费者consumer.xml---测试默认是随机策略

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
        <dubbo:application name="consumer-of-helloworld-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
        </dubbo:application>
    
        <!-- 使用multicast广播注册中心暴露发现服务地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
        <dubbo:reference id="dubboService" interface="dubbo.DubboService" />
    </beans>

    测试代码:

    package dubbo;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
        public static void main(String[] args) throws InterruptedException {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "consumer.xml" });
            context.start();
            for (int i = 0; i < 10; i++) {
                DubboService service = (DubboService) context.getBean("dubboService");
                System.out.println(service.sayHello(" china "));
            }
    
        }
    }

    结果:(4/6分,也就是随机策略的结果)

    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china
    Hello china
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china ,DubboServiceImpl2

    (5)策略改为轮询策略进行测试---loadbalance="roundrobin"

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
        <dubbo:application name="consumer-of-helloworld-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
        </dubbo:application>
    
        <!-- 使用multicast广播注册中心暴露发现服务地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
        <dubbo:reference id="dubboService" interface="dubbo.DubboService"
            loadbalance="roundrobin" />
    </beans>

    结果:(轮询的效果如下)

    Hello china ,DubboServiceImpl2
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china

    从dubbo-admin项目查看权重信息如下:

    (6)修改权重为300:100后再次测试以及查看

     修改provider.xml增加权重信息,consumer.xml同上

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="hello-world-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
            <dubbo:parameter key="qos.accept.foreign.ip" value="true" />
            <dubbo:parameter key="qos.port" value="2222" />
        </dubbo:application>
    
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="dubbo.DubboService" ref="demoService"
            weight="300" />
        <dubbo:service interface="dubbo.DubboService" ref="demoService2"
            weight="100" />
        <!-- 和本地bean一样实现服务 -->
        <bean id="demoService" class="dubbo.DubboServiceImpl" />
        <bean id="demoService2" class="dubbo.DubboServiceImpl2" />
    </beans>

     测试结果如下:

    Hello china
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china
    Hello china
    Hello china ,DubboServiceImpl2
    Hello china
    Hello china
    Hello china

    查看权重信息如下:

    2.    集群容错

      在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。

    各节点关系:

      这里的 Invoker 是 Provider 的一个可调用 Service 的抽象,Invoker 封装了 Provider 地址及 Service 接口信息
      Directory 代表多个 Invoker,可以把它看成 List<Invoker> ,但与 List 不同的是,它的值可能是动态变化的,比如注册中心推送变更
      Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个
      Router 负责从多个 Invoker 中按路由规则选出子集,比如读写分离,应用隔离等
      LoadBalance 负责从多个 Invoker 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选

    1.集群容错模式

    • Failover Cluster (默认值)

        失败自动切换,当出现失败,重试其它服务器 。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

    重试次数配置如下:

    <dubbo:service retries="2" />

    <dubbo:reference retries="2" />

    <dubbo:reference>
    <dubbo:method name="findFoo" retries="2" />
    </dubbo:reference>
    • Failfast Cluster

        快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

    • Failsafe Cluster

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

    • Failback Cluster

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

    • Forking Cluster

        并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

    • Broadcast Cluster

        广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息。

    2.    集群模式配置

    按照以下示例在服务提供方和消费方配置集群模式

    <dubbo:service cluster="failsafe" />

    <dubbo:reference cluster="failsafe" /> 

    3.测试

      服务实现类将其中一个休眠5秒钟。

    package dubbo;
    
    public class DubboServiceImpl2 implements DubboService {
        public String sayHello(String name) {
            try {
                Thread.sleep(5 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello " + name + ",DubboServiceImpl2";
        }
    }

     provider.xml如下:

    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 提供方应用信息,用于计算依赖关系 -->
        <dubbo:application name="hello-world-app">
            <!-- 关闭QOS:Quality of Service -->
            <dubbo:parameter key="qos.enable" value="false" />
            <dubbo:parameter key="qos.accept.foreign.ip" value="true" />
            <dubbo:parameter key="qos.port" value="2222" />
        </dubbo:application>
    
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 声明需要暴露的服务接口 -->
        <dubbo:service interface="dubbo.DubboService" ref="demoService"
            weight="300" />
        <dubbo:service interface="dubbo.DubboService" ref="demoService2"
            timeout="50000" weight="100" />
    
        <!-- 和本地bean一样实现服务 -->
        <bean id="demoService" class="dubbo.DubboServiceImpl" />
        <bean id="demoService2" class="dubbo.DubboServiceImpl2" />
    </beans>

    (1) 缺省Failover Cluster

      在服务消费者执行过程中,通过监控中心禁用某个服务提供者,执行结果显示能够正确切换到可用服务提供者,不会报错或者丢失调用。

     

    (2)设置为Failfast Cluster的时候

      当服务消费者调用某个服务提供者时,如果停掉该服务提供者,将立即报错并不继续执行。

    (3)设置为Failsafe Cluster的时候

      当服务消费者调用某个服务提供者时,如果停掉该服务提供者,直接忽略,继续往下走。

  • 相关阅读:
    【jsp】怎么在jsp文件中引入静态文件(.js .css)
    【MyBatis】MyBatis之分页
    【MyBatis】MyBatis之如何存储NULL
    【MyBatis】MyBatis之如何配置
    【MyBatis】MyBatis之别名typeAliases标签的使用
    【Spring】SpringMVC之详解AOP
    【Spring】SpringMVC之REST编程风格
    【Spring】SpringMVC之上传文件
    【Spring】SpringMVC之拦截器
    【Spring】SpringMVC之异常处理
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10595567.html
Copyright © 2011-2022 走看看