<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] > [參考](https://chai2010.cn/advanced-go-programming-book/ch6-cloud/ch6-05-load-balance.html) ## 概述 1. 按順序挑: 例如上次選了第一臺,那么這次就選第二臺,下次第三臺,如果已經到了最后一臺,那么下一次從第一臺開始。這種情況下我們可以把服務節點信息都存儲在數組中,每次請求完成下游之后,將一個索引后移即可。在移到盡頭時再移回數組開頭處。 2. 隨機挑一個: 每次都隨機挑,真隨機偽隨機均可。假設選擇第 x 臺機器,那么x可描述為`rand.Intn()%n`。 3. 根據某種權重,對下游節點進行排序,選擇權重最大/小的那一個。 ## 基于洗牌算法的負載均衡 考慮到我們需要隨機選取每次發送請求的節點,同時在遇到下游返回錯誤時換其它節點重試。所以我們設計一個大小和節點數組大小一致的索引數組,每次來新的請求,我們對索引數組做洗牌,然后取第一個元素作為選中的服務節點,如果請求失敗,那么選擇下一個節點重試 ``` var endpoints = []string { "100.69.62.1:3232", "100.69.62.32:3232", "100.69.62.42:3232", "100.69.62.81:3232", "100.69.62.11:3232", "100.69.62.113:3232", "100.69.62.101:3232", } // 重點在這個 shuffle func shuffle(slice []int) { for i := 0; i < len(slice); i++ { a := rand.Intn(len(slice)) b := rand.Intn(len(slice)) slice[a], slice[b] = slice[b], slice[a] } } func request(params map[string]interface{}) error { var indexes = []int {0,1,2,3,4,5,6} var err error shuffle(indexes) maxRetryTimes := 3 idx := 0 for i := 0; i < maxRetryTimes; i++ { err = apiRequest(params, indexes[idx]) if err == nil { break } idx++ } if err != nil { // logging return err } return nil } ``` **錯誤的洗牌導致的負載不均衡** 1. 沒有隨機種子。在沒有隨機種子的情況下,`rand.Intn()`返回的偽隨機數序列是固定的。 2. 洗牌不均勻,會導致整個數組第一個節點有大概率被選中,并且多個節點的負載分布不均衡。 第一點比較簡單,應該不用在這里給出證明了。關于第二點,我們可以用概率知識來簡單證明一下。假設每次挑選都是真隨機,我們假設第一個位置的節點在`len(slice)`次交換中都不被選中的概率是`((6/7)*(6/7))^7 ≈ 0.34`。而分布均勻的情況下,我們肯定希望被第一個元素在任意位置上分布的概率均等,所以其被隨機選到的概率應該約等于`1/7≈0.14` ### ZooKeeper 集群的隨機節點挑選問題 使用ZooKeeper時,客戶端初始化從多個服務節點中挑選一個節點后,是會向該節點建立長連接的。之后客戶端請求都會發往該節點去。直到該節點不可用,才會在節點列表中挑選下一個節點。在這種場景下,我們的初始連接節點選擇就要求必須是“真”隨機了。否則,所有客戶端起動時,都會去連接同一個ZooKeeper的實例,根本無法起到負載均衡的目的。如果在日常開發中,你的業務也是類似的場景,也務必考慮一下是否會發生類似的情況。為rand庫設置種子的方法 ``` rand.Seed(time.Now().UnixNano()) ``` ### 負載均衡算法效果驗證 ``` ackage main import ( "fmt" "math/rand" "time" ) func init() { rand.Seed(time.Now().UnixNano()) } func shuffle1(slice []int) { for i := 0; i < len(slice); i++ { a := rand.Intn(len(slice)) b := rand.Intn(len(slice)) slice[a], slice[b] = slice[b], slice[a] } } func shuffle2(indexes []int) { for i := len(indexes); i > 0; i-- { lastIdx := i - 1 idx := rand.Intn(i) indexes[lastIdx], indexes[idx] = indexes[idx], indexes[lastIdx] } } func main() { var cnt1 = map[int]int{} for i := 0; i < 1000000; i++ { var sl = []int{0, 1, 2, 3, 4, 5, 6} shuffle1(sl) cnt1[sl[0]]++ } var cnt2 = map[int]int{} for i := 0; i < 1000000; i++ { var sl = []int{0, 1, 2, 3, 4, 5, 6} shuffle2(sl) cnt2[sl[0]]++ } fmt.Println(cnt1, "\n", cnt2) } ``` 輸出: ``` map[0:224436 1:128780 5:129310 6:129194 2:129643 3:129384 4:129253] map[6:143275 5:143054 3:143584 2:143031 1:141898 0:142631 4:142527] ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看