日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言


19年我幾乎把阿里很多部門都面過,那一年也是行情最好的一年,icbu、uc、淘系、烏鶇、ae、上海支付寶(剛好有朋友在那),那會真的慘烈,被摁在地上摩擦,不過我也因此全方面的對自己有了一次認識,知道了基礎知識(八股文)不熟,在技術深度上欠缺。最后是拿了淘系的offer,不容易啊~

每次面試都是對過往的review,也是自我提升的墊腳石

最近在搞流量負載相關的東西,順便就溫故下負載均衡算法,然后也玩了一下ChatGPT,發現很強大,給的代碼demo都很詳細,感覺百度都可有可無了,hhh

 

負載均衡算法有哪些


 

我感覺可以讓gpt幫我寫篇文章了,笑死。

  1. 輪訓
  2. 隨機
  3. 最小活躍數
  4. 權重
  5. 自適應 6.so on...

前兩個我們就不用說了,從第三點來聊聊

最小活躍數

什么是活躍數?它儲存在哪里?為什么要這么做?

這里的活躍數指的是dubbo連接數,就是客戶端對服務端的連接數有多少,它會優先指向連接數小的。它儲存在客戶端,也就是說每次請求會給連接+1,釋放的時候又會-1。為什么這么做呢?為了分攤壓力,讓空閑的服務端多接點流量。

邏輯:從客戶端的記錄里面摟出哪個服務端連接數最小,如果有并列則看權重,如果權重一樣則隨機。

public class LeastActiveLoadBalance extends AbstractLoadBalance {
    public static final String NAME = "leastactive";

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int length = invokers.size(); // 總個數
        int leastActive = -1; // 最小的活躍數
        int leastCount = 0; // 相同最小活躍數的個數
        int[] weights = new int[length]; // 權重
        int totalWeight = 0; // 總權重
        for (int i = 0; i < length; i++) {
            Invoker<T> invoker = invokers.get(i);
            int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive(); // 活躍數
            int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT); // 權重
            if (leastActive == -1 || active < leastActive) { // 發現更小的活躍數,重新開始
                leastActive = active; // 記錄最小活躍數
                leastCount = 1; // 重新統計相同最小活躍數的個數
                weights[0] = weight; // 將當前權重記錄下來,留作備選
                totalWeight = weight; // 初始化總權重
            } else if (active == leastActive) { // 累計相同最小的活躍數
                weights[leastCount++] = weight; // 將當前權重記錄下來,留作備選
                totalWeight += weight; // 累加權重
            }
        }
        if (leastCount == 1) { // 如果只有一個最小則直接返回
            return invokers.get(0);
        }
        // 如果權重不相等且權重大于0則按權重分配,否則隨機分配
        return selectByRandomWeight(invokers, weights, totalWeight);
    }
}

復制代碼

加權負載

這個就是我們人為給這些dubbo服務端加上權重,這樣做的好處就是我們本來就是知道那臺服務器配置比較牛,它可以承受更多的請求,這樣我們讓流量更多的打到它上面,更好利用資源。

基于rt自適應負載均衡

這個一開始我在博客看到的,就是講dubbo3對這塊會有關于cpu還有類似rt相關自適應的負載均衡

我看阿里的天池比賽中,看到這樣一個根據rt來做負載均衡的,大家可以觀摩一哈

  • [complone/dubbo-loadbalance](Github.com/complone/du…)
package com.aliware.tianchi;

import org.Apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.LoadBalance;

import com.aliware.tianchi.comm.CustomerInfo;

import JAVA.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author complone
 */
public class UserLoadBalance implements LoadBalance {

    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {

        //1、所有服務器爭取每個打一次請求
        Invoker invoker = doSelectInFreeInvokers(invokers);

        //2、根據服務端信息分配權重
        invoker = invoker != null ? invoker : doSelectWithWeigth(invokers);

        return invoker;
    }

    /**
     * 落實優先每個機器都有流量請求
     */
    private <T> Invoker<T> doSelectInFreeInvokers(List<Invoker<T>> invokers) {

        if (CustomerInfoManager.LOAD_INFO.size() < invokers.size()) {
            for (Invoker invoker : invokers) {

                CustomerInfo customerInfo = CustomerInfoManager.getServerLoadInfo(invoker);

                if (customerInfo != null) break;

                return invoker;
            }
        }

        return null;
    }

    /**
     * 根據服務端配置和平均耗時計算權重
     */
    private <T> Invoker<T> doSelectWithWeigth(List<Invoker<T>> invokers) {

        // 重新分配權重的<服務,權重>映射
        int[] serviceWeight = new int[invokers.size()];

        // 總權重
        int totalWeight = 0;

        // 1、計算總權重
        for (int index = 0, size = invokers.size(); index < size; ++index) {

            Invoker<T> invoker = invokers.get(index);

            CustomerInfo customerInfo = CustomerInfoManager.getServerLoadInfo(invoker);
            AtomicInteger availThreadAtomic = CustomerInfoManager.getAvailThread(invoker);

            if (customerInfo != null) {

                if (availThreadAtomic.get() > 0) {
                    int weight = customerInfo.getServerWeight();
                    //根據耗時重新計算權重(基本權重*(1秒/單個請求耗時))
                    int clientTimeAvgSpendCurr = customerInfo.getAvgSpendTime();
                    if (clientTimeAvgSpendCurr == 0) {
                        // 耗時為0,性能優,請求直接打到該機器
                        // 也有可能是性能差,采用隨機
                        return invokers.get(ThreadLocalRandom.current().nextInt(invokers.size()));
                    }

                    // 計算權重
                    weight = weight * (500 / clientTimeAvgSpendCurr);
                    serviceWeight[index] = weight;
                    totalWeight = totalWeight + weight;
                }
            }
        }

        // 2、按照新的權重選擇服務,權重加權隨機算法
        int oneWeight = ThreadLocalRandom.current().nextInt(totalWeight);

        for (int i = 0, size = invokers.size(); i < size; ++i) {
            oneWeight -= serviceWeight[i];
            if (oneWeight < 0) {
                return invokers.get(i);
            }
        }

        //兜底采用隨機算法
        return invokers.get(ThreadLocalRandom.current().nextInt(invokers.size()));
    }
}
復制代碼

首先是
customerInfo.getAvgSpendTime(),就是客戶端會保持每個服務端請求次數、總的請求時間,這樣平均響應時間就出來了,這里為什么要用500去除,而不是其他數字呢?我沒有仔細看內部細節,當分母越大,這個數越小,也就是rt越長,服務節點性能越差,對應的權重會越小,這個思想我們還是能理解的。

int oneWeight = ThreadLocalRandom.current().nextInt(totalWeight); 
for (int i = 0, size = invokers.size(); i < size; ++i) { 
    oneWeight -= serviceWeight[i]; 
    if (oneWeight < 0) { 
        return invokers.get(i); 
     } 
}
復制代碼

這塊有點意思了,大家看得懂嗎?讓我想起之前抽獎算法,比如說a商品有40%,b商品有60%幾率,怎么去抽獎呢?

同比比例擴大,比如說a有4個商品,b有6個商品,你去隨機抽一個,是不是有那味了,哈哈。同樣這里也是,就是我們把所有服務器節點的權重拿到了,總計一個總的權重,然后我們生成一個隨機數,那么看它最后是命中那個節點,當權重大的它會更有幾率命中,是這么個意思~

那基于cpu呢?

基于cpu自適應負載均衡

 

最重要就這些數據指標怎么拿到,chatgpt已經跟我講了,可以通過grafana類似運維監控工具來提供,如何跟dubbo結合起來?如果這些數據沒有拿到怎么兜底?

這個思路可以參考服務注冊中心,其實就是pingpong,異步定期去拉取數據然后存到本地緩存里面,具體拉取的頻率怎樣,根據實際情況決定要多久去拉取,其次是訪問量,比如說有很多節點請求次數頻繁,那么就啟用緩存,先把數據存緩存,dubbo直接讀取緩存數據即可。最后兜底方案比如說讀不到服務cpu值,那么直接換負載算法兜底。

總結


流量負載算法是一種常用的負載均衡策略,它可以將網絡流量分配到多個服務器上,從而提高系統的性能和可靠性。常見的流量負載算法包括輪詢、加權輪詢、最小連接數等。在選擇合適的負載均衡算法時,需要考慮服務器的性能、網絡拓撲結構以及用戶訪問模式等因素。同時,為了保證系統的可靠性,需要采取故障轉移和容錯機制。


原文鏈接:
https://juejin.cn/post/7212616585768009787

分享到:
標簽:算法
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定