Skip to content

Commit

Permalink
add weighted_lb feature
Browse files Browse the repository at this point in the history
  • Loading branch information
liangwei3 committed Apr 3, 2024
1 parent 48275d7 commit 1a28f02
Showing 1 changed file with 37 additions and 30 deletions.
67 changes: 37 additions & 30 deletions lb/weightRoundRobinLb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestDynamicStaticWeight(t *testing.T) {

meta.ClearMetaCache()
var staticWeight int64 = 9
eps := buildTestDynamicEps(10, true, staticWeight)
eps := buildTestDynamicEps(10, true, staticWeight, url)
eps = core.EndpointShuffle(eps)
lb.OnRefresh(eps)
_, ok := lb.getSelector().(*roundRobinSelector)
Expand Down Expand Up @@ -128,9 +128,10 @@ func TestNotifyWeightChange(t *testing.T) {
Port: 8080,
Path: "mockService",
}
url.PutParam(core.DynamicMetaKey, "false")
lb := NewWeightRondRobinLb(url)
for _, j := range testSet {
eps := buildTestDynamicEps(j.size, j.sameWeight, int64(j.maxWeight))
eps := buildTestDynamicEps(j.size, j.sameWeight, int64(j.maxWeight), url)
eps = core.EndpointShuffle(eps)
lb.OnRefresh(eps)
var ok bool
Expand All @@ -155,27 +156,28 @@ func TestRoundRobinSelector(t *testing.T) {
Port: 8080,
Path: "mockService",
}
url.PutParam(core.DynamicMetaKey, "false")
lb := NewWeightRondRobinLb(url)
round := 100
// small size
checkRR(t, lb, 20, 8, round, 1, 1, 0)
checkRR(t, lb, 20, 8, round, 1, 1, 0, url)
// large size
checkRR(t, lb, 500, 8, round, 1, 1, 0)
checkRR(t, lb, 500, 8, round, 1, 1, 0, url)
// some nodes are unavailable
maxRatio := 0.4
avgRatio := 0.1
round = 200
checkRR(t, lb, 20, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 2)
checkRR(t, lb, 100, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 10)
checkRR(t, lb, 20, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 2, url)
checkRR(t, lb, 100, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 10, url)

maxRatio = 0.7
checkRR(t, lb, 300, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 50)
checkRR(t, lb, 300, 8, round, float64(round)*maxRatio, float64(round)*avgRatio, 50, url)
lb.Destroy()
}

func checkRR(t *testing.T, lb *WeightRoundRobinLB, size int, initialMaxWeight int64,
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int) {
eps := buildTestDynamicEpsWithUnavailable(size, true, initialMaxWeight, true, unavailableSize)
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int, url *core.URL) {
eps := buildTestDynamicEpsWithUnavailable(size, true, initialMaxWeight, true, unavailableSize, url)
eps = core.EndpointShuffle(eps)
lb.OnRefresh(eps)
_, ok := lb.getSelector().(*roundRobinSelector)
Expand All @@ -190,26 +192,27 @@ func TestWeightRingSelector(t *testing.T) {
Port: 8080,
Path: "mockService",
}
url.PutParam(core.DynamicMetaKey, "false")
lb := NewWeightRondRobinLb(url)
round := 100
// small size
checkKWR(t, lb, 51, 49, round, 1, 1, 0)
checkKWR(t, lb, 51, 49, round, 1, 1, 0, url)
// max node size of WR
checkKWR(t, lb, 256, 15, round, 1, 1, 0)
checkKWR(t, lb, 256, 15, round, 1, 1, 0, url)

// same nodes are unavailable
maxRatio := 0.4
avgRatio := 0.1
checkKWR(t, lb, 46, 75, round, float64(round)*maxRatio, float64(round)*avgRatio, 5)
checkKWR(t, lb, 231, 31, round, float64(round)*maxRatio, float64(round)*avgRatio, 35)
checkKWR(t, lb, 46, 75, round, float64(round)*maxRatio, float64(round)*avgRatio, 5, url)
checkKWR(t, lb, 231, 31, round, float64(round)*maxRatio, float64(round)*avgRatio, 35, url)
maxRatio = 0.6
checkKWR(t, lb, 211, 31, round, float64(round)*maxRatio, float64(round)*avgRatio, 45)
checkKWR(t, lb, 211, 31, round, float64(round)*maxRatio, float64(round)*avgRatio, 45, url)
lb.Destroy()
}

func checkKWR(t *testing.T, lb *WeightRoundRobinLB, size int, initialMaxWeight int64,
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int) {
eps := buildTestDynamicEpsWithUnavailable(size, false, initialMaxWeight, true, unavailableSize)
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int, url *core.URL) {
eps := buildTestDynamicEpsWithUnavailable(size, false, initialMaxWeight, true, unavailableSize, url)
eps = core.EndpointShuffle(eps)
lb.OnRefresh(eps)
_, ok := lb.getSelector().(*weightedRingSelector)
Expand All @@ -224,34 +227,35 @@ func TestSlidingWindowWeightedRoundRobinSelector(t *testing.T) {
Port: 8080,
Path: "mockService",
}
url.PutParam(core.DynamicMetaKey, "false")
lb := NewWeightRondRobinLb(url)
round := 100
// equals default window size, the accuracy is higher than sliding window
size := swwrDefaultWindowSize
//checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, 2, 1, 0)
checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, 2, 1, 0, url)
// less than default window size
size = swwrDefaultWindowSize - 9
checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, 2, 1, 0)
checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, 2, 1, 0, url)

// greater than default window size
// sliding windows will reduce the accuracy of WRR, so the threshold should be appropriately increased
maxRatio := 0.5
avgRatio := 0.1
round = 200
size = 270
checkSWWRR(t, lb, size, 45, round, float64(round)*maxRatio, float64(round)*avgRatio, 0)
checkSWWRR(t, lb, size, 45, round, float64(round)*maxRatio, float64(round)*avgRatio, 0, url)

// some nodes are unavailable
size = 260
checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, float64(round)*maxRatio, float64(round)*avgRatio, 10)
checkSWWRR(t, lb, size, int64(wrMaxTotalWeight*3/size), round, float64(round)*maxRatio, float64(round)*avgRatio, 10, url)
size = 399
checkSWWRR(t, lb, size, 67, round, float64(round)*maxRatio, float64(round)*avgRatio, 40)
checkSWWRR(t, lb, size, 67, round, float64(round)*maxRatio, float64(round)*avgRatio, 40, url)
lb.Destroy()
}

func checkSWWRR(t *testing.T, lb *WeightRoundRobinLB, size int, initialMaxWeight int64,
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int) {
eps := buildTestDynamicEpsWithUnavailable(size, false, initialMaxWeight, true, unavailableSize)
round int, expectMaxDelta float64, expectAvgDelta float64, unavailableSize int, url *core.URL) {
eps := buildTestDynamicEpsWithUnavailable(size, false, initialMaxWeight, true, unavailableSize, url)
eps = core.EndpointShuffle(eps)
lb.OnRefresh(eps)
_, ok := lb.getSelector().(*slidingWindowWeightedRoundRobinSelector)
Expand Down Expand Up @@ -300,15 +304,15 @@ func processCheck(t *testing.T, lb *WeightRoundRobinLB, typ string, eps []core.E
}
}

func buildTestDynamicEps(size int, sameStaticWeight bool, maxWeight int64) []core.EndPoint {
return buildTestDynamicEpsWithUnavailable(size, sameStaticWeight, maxWeight, false, 0)
func buildTestDynamicEps(size int, sameStaticWeight bool, maxWeight int64, url *core.URL) []core.EndPoint {
return buildTestDynamicEpsWithUnavailable(size, sameStaticWeight, maxWeight, false, 0, url)
}

func buildTestDynamicEpsWithUnavailable(size int, sameStaticWeight bool, maxWeight int64, adjust bool, unavailableSize int) []core.EndPoint {
return buildTestEps(size, sameStaticWeight, maxWeight, adjust, unavailableSize, "")
func buildTestDynamicEpsWithUnavailable(size int, sameStaticWeight bool, maxWeight int64, adjust bool, unavailableSize int, url *core.URL) []core.EndPoint {
return buildTestEps(size, sameStaticWeight, maxWeight, adjust, unavailableSize, "", url)
}

func buildTestEps(size int, sameStaticWeight bool, maxWeight int64, adjust bool, unavailableSize int, group string) []core.EndPoint {
func buildTestEps(size int, sameStaticWeight bool, maxWeight int64, adjust bool, unavailableSize int, group string, url *core.URL) []core.EndPoint {
var res []core.EndPoint
for i := 0; i < size; i++ {
weight := maxWeight
Expand All @@ -318,13 +322,16 @@ func buildTestEps(size int, sameStaticWeight bool, maxWeight int64, adjust bool,
if adjust {
weight = doAdjust(weight)
}
url := &core.URL{
curUrl := &core.URL{
Protocol: "motan2",
Host: "127.0.0.1",
Port: 8080 + i,
Path: "mockService",
}
ep := endpoint.NewMockDynamicEndpointWithWeight(url, weight)
if url.GetParam(core.DynamicMetaKey, "") == "false" {
curUrl.PutParam(core.DynamicMetaKey, "false")
}
ep := endpoint.NewMockDynamicEndpointWithWeight(curUrl, weight)
if i < unavailableSize {
ep.SetAvailable(false)
}
Expand Down

0 comments on commit 1a28f02

Please sign in to comment.