關於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

    }
}


這裏的代碼可以借鑑源碼給予我們的再進行修改即可.

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