亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

不提供 http 服務時的 golang 客戶端負載均衡器

不提供 http 服務時的 golang 客戶端負載均衡器

Go
慕森王 2023-06-19 11:09:45
作為一個golang n00b,我有一個 go 程序,它將消息讀入 kafka,修改它們,然后將它們發布到列表中的一個 http 端點。到目前為止,我們用隨機數做了一些非?;镜难hcur?:=?rand.Int()?%?len(httpEndpointList)我想改進它并根據端點的響應時間或類似的東西增加端點的權重。我查看了庫,但我似乎發現的所有內容都是為使用 http.Handle 用作中間件而編寫的。我的情況是,我不為每個人提供 http 請求。任何想法我怎么能在我的 golang 程序中完成那種更高級的客戶端負載平衡?我想避免在我的環境中使用另一個 haproxy 或類似的。
查看完整描述

1 回答

?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

有一個非常簡單的加權隨機選擇算法:


package main


import (

    "fmt"

    "math/rand"

)


type Endpoint struct {

    URL    string

    Weight int

}


func RandomWeightedSelector(endpoints []Endpoint) Endpoint {

    // this first loop should be optimised so it only gets computed once

    max := 0

    for _, endpoint := range endpoints {

        max = max + endpoint.Weight

    }


    r := rand.Intn(max)

    for _, endpoint := range endpoints {

        if r < endpoint.Weight {

            return endpoint

        } else {

            r = r - endpoint.Weight

        }

    }

    // should never get to this point because r is smaller than max

    return Endpoint{}

}


func main() {

    endpoints := []Endpoint{

        {Weight: 1, URL: "https://web1.example.com"},

        {Weight: 2, URL: "https://web2.example.com"},

    }


    count1 := 0

    count2 := 0


    for i := 0; i < 100; i++ {

        switch RandomWeightedSelector(endpoints).URL {

        case "https://web1.example.com":

            count1++

        case "https://web2.example.com":

            count2++

        }

    }

    fmt.Println("Times web1: ", count1)

    fmt.Println("Times web2: ", count2)

}

在可以優化的情況下,這是最幼稚的。當然對于生產你不應該每次都計算最大值,但除此之外,這基本上是解決方案。


這是一個更專業和面向對象的版本,不會每次都重新計算最大值:


package main


import (

    "fmt"

    "math/rand"

)


type Endpoint struct {

    URL    string

    Weight int

}


type RandomWeightedSelector struct {

    max       int

    endpoints []Endpoint

}


func (rws *RandomWeightedSelector) AddEndpoint(endpoint Endpoint) {

    rws.endpoints = append(rws.endpoints, endpoint)

    rws.max += endpoint.Weight

}


func (rws *RandomWeightedSelector) Select() Endpoint {

    r := rand.Intn(rws.max)

    for _, endpoint := range rws.endpoints {

        if r < endpoint.Weight {

            return endpoint

        } else {

            r = r - endpoint.Weight

        }

    }

    // should never get to this point because r is smaller than max

    return Endpoint{}

}


func main() {

    var rws RandomWeightedSelector

    rws.AddEndpoint(Endpoint{Weight: 1, URL: "https://web1.example.com"})

    rws.AddEndpoint(Endpoint{Weight: 2, URL: "https://web2.example.com"})


    count1 := 0

    count2 := 0


    for i := 0; i < 100; i++ {

        switch rws.Select().URL {

        case "https://web1.example.com":

            count1++

        case "https://web2.example.com":

            count2++

        }

    }

    fmt.Println("Times web1: ", count1)

    fmt.Println("Times web2: ", count2)

}

對于基于端點延遲等指標更新權重的部分,我將創建一個不同的對象,該對象使用此指標來更新 RandomWeightedSelector 對象中的權重。我認為一起實施它會違反單一責任。


查看完整回答
反對 回復 2023-06-19
  • 1 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號