亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Ribbon的負載均衡策略及原理是什么

發布時間:2021-07-08 18:02:26 來源:億速云 閱讀:178 作者:chen 欄目:大數據

本篇內容介紹了“Ribbon的負載均衡策略及原理是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    Load Balance負載均衡是用于解決一臺機器(一個進程)無法解決所有請求而產生的一種算法。像nginx可以使用負載均衡分配流量,ribbon為客戶端提供負載均衡,dubbo服務調用里的負載均衡等等,很多地方都使用到了負載均衡。

使用負載均衡帶來的好處很明顯:

當集群里的1臺或者多臺服務器down的時候,剩余的沒有down的服務器可以保證服務的繼續使用
使用了更多的機器保證了機器的良性使用,不會由于某一高峰時刻導致系統cpu急劇上升
負載均衡有好幾種實現策略,常見的有:

隨機 (Random)
輪詢 (RoundRobin)
一致性哈希 (ConsistentHash)
哈希 (Hash)
加權(Weighted)


ILoadBalance 負載均衡器

ribbon是一個為客戶端提供負載均衡功能的服務,它內部提供了一個叫做ILoadBalance的接口代表負載均衡器的操作,比如有添加服務器操作、選擇服務器操作、獲取所有的服務器列表、獲取可用的服務器列表等等。ILoadBalance的繼承關系如下:

Ribbon的負載均衡策略及原理是什么

負載均衡器是從EurekaClient(EurekaClient的實現類為DiscoveryClient)獲取服務信息,根據IRule去路由,并且根據IPing判斷服務的可用性。

負載均衡器多久一次去獲取一次從Eureka Client獲取注冊信息呢?在BaseLoadBalancer類下,BaseLoadBalancer的構造函數,該構造函數開啟了一個PingTask任務setupPingTask();,代碼如下:

    public BaseLoadBalancer(String name, IRule rule, LoadBalancerStats stats,
            IPing ping, IPingStrategy pingStrategy) {
        if (logger.isDebugEnabled()) {
            logger.debug("LoadBalancer:  initialized");
        }
        this.name = name;
        this.ping = ping;
        this.pingStrategy = pingStrategy;
        setRule(rule);
        setupPingTask();
        lbStats = stats;
        init();
    }


setupPingTask()的具體代碼邏輯,它開啟了ShutdownEnabledTimer執行PingTask任務,在默認情況下pingIntervalSeconds為10,即每10秒鐘,向EurekaClient發送一次”ping”。

void setupPingTask() {
        if (canSkipPing()) {
            return;
        }
        if (lbTimer != null) {
            lbTimer.cancel();
        }
        lbTimer = new ShutdownEnabledTimer("NFLoadBalancer-PingTimer-">


PingTask源碼,即new一個Pinger對象,并執行runPinger()方法。

查看Pinger的runPinger()方法,最終根據 pingerStrategy.pingServers(ping, allServers)來獲取服務的可用性,如果該返回結果,如之前相同,則不去向EurekaClient獲取注冊列表,如果不同則通知ServerStatusChangeListener或者changeListeners發生了改變,進行更新或者重新拉取。

完整過程是:

LoadBalancerClient(RibbonLoadBalancerClient是實現類)在初始化的時候(execute方法),會通過ILoadBalance(BaseLoadBalancer是實現類)向Eureka注冊中心獲取服務注冊列表,并且每10s一次向EurekaClient發送“ping”,來判斷服務的可用性,如果服務的可用性發生了改變或者服務數量和之前的不一致,則從注冊中心更新或者重新拉取。LoadBalancerClient有了這些服務注冊列表,就可以根據具體的IRule來進行負載均衡。

IRule 路由

IRule接口代表負載均衡策略:

public interface IRule{
    public Server choose(Object key);
    public void setLoadBalancer(ILoadBalancer lb);
    public ILoadBalancer getLoadBalancer();    
}


IRule接口的實現類有以下幾種:

Ribbon的負載均衡策略及原理是什么

Ribbon的負載均衡策略及原理是什么

其中RandomRule表示隨機策略、RoundRobinRule表示輪詢策略、WeightedResponseTimeRule表示加權策略、BestAvailableRule表示請求數最少策略等等。

隨機策略很簡單,就是從服務器中隨機選擇一個服務器,RandomRule的實現代碼如下:

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) {
            return null;
        }
        int index = rand.nextInt(serverCount); // 使用jdk內部的Random類隨機獲取索引值index
        server = upList.get(index); // 得到服務器實例
 
        if (server == null) {
            Thread.yield();
            continue;
        }
 
        if (server.isAlive()) {
            return (server);
        }
 
        server = null;
        Thread.yield();
    }
    return server;
}


RoundRobinRule輪詢策略表示每次都取下一個服務器,比如一共有5臺服務器,第1次取第1臺,第2次取第2臺,第3次取第3臺,以此類推:

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }
 
        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers();
            List<Server> allServers = lb.getAllServers();
            int upCount = reachableServers.size();
            int serverCount = allServers.size();
 
            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: ">


WeightedResponseTimeRule繼承了RoundRobinRule,開始的時候還沒有權重列表,采用父類的輪詢方式,有一個默認每30秒更新一次權重列表的定時任務,該定時任務會根據實例的響應時間來更新權重列表,choose方法做的事情就是,用一個(0,1)的隨機double數乘以最大的權重得到randomWeight,然后遍歷權重列表,找出第一個比randomWeight大的實例下標,然后返回該實例,代碼略。

BestAvailableRule策略用來選取最少并發量請求的服務器:

public Server choose(Object key) {
    if (loadBalancerStats == null) {
        return super.choose(key);
    }
    List<Server> serverList = getLoadBalancer().getAllServers(); // 獲取所有的服務器列表
    int minimalConcurrentConnections = Integer.MAX_VALUE;
    long currentTime = System.currentTimeMillis();
    Server chosen = null;
    for (Server server: serverList) { // 遍歷每個服務器
        ServerStats serverStats = loadBalancerStats.getSingleServerStat(server); // 獲取各個服務器的狀態
        if (!serverStats.isCircuitBreakerTripped(currentTime)) { // 沒有觸發斷路器的話繼續執行
            int concurrentConnections = serverStats.getActiveRequestsCount(currentTime); // 獲取當前服務器的請求個數
            if (concurrentConnections < minimalConcurrentConnections) { // 比較各個服務器之間的請求數,然后選取請求數最少的服務器并放到chosen變量中
                minimalConcurrentConnections = concurrentConnections;
                chosen = server;
            }
        }
    }
    if (chosen == null) { // 如果沒有選上,調用父類ClientConfigEnabledRoundRobinRule的choose方法,也就是使用RoundRobinRule輪詢的方式進行負載均衡        
        return super.choose(key);
    } else {
        return chosen;
    }
}


使用Ribbon提供的負載均衡策略很簡單,只需以下幾部:

1、創建具有負載均衡功能的RestTemplate實例

@Bean
@LoadBalanced
RestTemplate restTemplate() {
    return new RestTemplate();
}


使用RestTemplate進行rest操作的時候,會自動使用負載均衡策略,它內部會在RestTemplate中加入LoadBalancerInterceptor這個攔截器,這個攔截器的作用就是使用負載均衡。
默認情況下會采用輪詢策略,如果希望采用其它策略,則指定IRule實現,如:

@Bean
public IRule ribbonRule() {
    return new BestAvailableRule();
}


這種方式對Feign也有效。

我們也可以參考ribbon,自己寫一個負載均衡實現類。

可以通過下面方法獲取負載均衡策略最終選擇了哪個服務實例:

@Autowired
    LoadBalancerClient loadBalancerClient; 
    
    //測試負載均衡最終選中哪個實例
    public String getChoosedService() {
        ServiceInstance serviceInstance = loadBalancerClient.choose("USERINFO-SERVICE");
        StringBuilder sb = new StringBuilder();
        sb.append("host: ").append(serviceInstance.getHost()).append(", ");
        sb.append("port: ").append(serviceInstance.getPort()).append(", ");
        sb.append("uri: ").append(serviceInstance.getUri());
        return sb.toString();
    }

“Ribbon的負載均衡策略及原理是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤庆县| 乐安县| 遂宁市| 大宁县| 岳阳县| 郴州市| 东阿县| 高唐县| 涡阳县| 张北县| 化德县| 理塘县| 长丰县| 麦盖提县| 怀集县| 涿州市| 宁陕县| 宣恩县| 东城区| 巴中市| 秦皇岛市| 通城县| 定日县| 灵寿县| 交城县| 蛟河市| 濮阳县| 花垣县| 攀枝花市| 祁连县| 屏东县| 久治县| 宜川县| 万山特区| 长寿区| 治县。| 瓦房店市| 红桥区| 盐源县| 沂水县| 古浪县|