关于Ribbon做负载均衡的一些小案例.

在这一章我们要学习ribbon如何做负载均衡,从我上面的服务消费者和服务提供者的案例来看.由于上诉案例中只有一个数据库,所以我们在模拟负载均衡场景的时候应该要考虑多个数据库.浅显的将,就是我们在查询数据库服务时,我们希望服务器不会总是从一个数据库上查询.而是从不同的数据库中查询相同的数据,这样能减少数据库的压力.
  首先,我们先多建两个数据库,数据库中的数据都是一样的.但是为了看出数据库的差异,我们需要知道当前的数据是从哪一个数据库中查询,所以说我们会在每个数据库后面的字段加上当前的数据库名.如下图:
在这里插入图片描述当然我们也需要多准备两个服务提供者端口:8002,8003.分别绑定对应的数据库如下图:
在这里插入图片描述点击网址查看eureka7001.com/7001
在这里插入图片描述我们可以发现这里已经有了三个实例
上诉操作完后,我们在浏览器中输入网址localhost/consumer/dept/list.
就能查看数据库中的数据.而且每次刷新网页就能是从不同的数据库中查询出来的,
但是刷新几次后我们会发现,这是一个有规律的查询方式.
这里就又要谈到一个接口IRule.这个接口里面有很多写好的一些负载均衡算法:
在这里插入图片描述当然像我们上面的那种有规律的查询就是这里方法中的RoundRobinRule.策称为轮询规则.源码如下:
在这里插入图片描述其中还有一些常用的比如随机算法,
在这里插入图片描述还有一种是WeightedResponseTimeRule权重算法,计算加权
RetryRule:重试策略,会先按照轮询获取服务,如果服务获取失败,则会在指定的时间内进行重试.
AvailabilityFilteringRule:会先过滤掉崩溃的服务,跳闸的服务(访问故障).对剩下的进行轮询
这些是源码中提供给我们的一些策略,当然我们可以自己自定义一些算法.
步骤如下:
我们需要在不同于主启动类的包下新建一个包比如:
在这里插入图片描述第一步:需要在ConfigBean中注册我们自定义的策略,然后添加@Bean,交由spring托管.

@Bean
    public IRule MyIRule(){
        return new MyRule();//默认的是轮询,现在我们自定义的就是我们自己写的算法
}

第二步: 在主启动类中添加注释@@RibbonClient,在微服务加载的时候就能区域加载我们自定义的Ribbon类

//在微服务加载的时候就能区域加载我们自定义的Ribbon类
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)

第三步:编写自定义策略代码:

package com.qiu.myRule;


import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class MyRule extends AbstractLoadBalancerRule {

//要求就是每个机器访问5次,然后换下一个服务(3个)
    //大于三个就置于0
    //total=0.默认的也是0,如果=5我们就指向下一个节点
    //index=0,默认0,如果total=5,那么index+1,如果index=3,那么就将index置为0
    private int total = 0;//被调用的次数
    private int currentIndex = 0;//当前是谁在提供服务
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }

            List<Server> upList = lb.getReachableServers();//获得活着的服务
            List<Server> allList = lb.getAllServers();//获得全部的服务

            int serverCount = allList.size();
            if (serverCount == 0) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }
//            int index = chooseRandomInt(serverCount);//生成区间随机数
//            server = upList.get(index);//从活着的服务中随机获取一个
            //==============================================
            if(total<5){
                server = upList.get(currentIndex);
                total++;
            }else {
                total=0;
                currentIndex++;
                if (currentIndex>upList.size()){//当前的服务(第几个)大于最大的,则将服务置为最开始的那一个
                    currentIndex=0;
                }
                server = upList.get(currentIndex);//从活着的服务中获取指定的服务进行操作
            }







            //=======================================
            if (server == null) {
                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }


            server = null;
            Thread.yield();
        }

        return server;

    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        // TODO Auto-generated method stub

    }
}


这里的代码可以借鉴源码给予我们的再进行修改即可.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章