Add interleaved weighted round-robin and alias-method loadbalancer (#2606)
diff --git a/cluster/loadbalance/aliasmethod/alias_method.go b/cluster/loadbalance/aliasmethod/alias_method.go
new file mode 100644
index 0000000..10c49cd
--- /dev/null
+++ b/cluster/loadbalance/aliasmethod/alias_method.go
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package aliasmethod implements alias-method algorithm load balance strategy.
+package aliasmethod // weighted random with alias-method algorithm
+
+import (
+ "math/rand"
+
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+)
+
+type aliasMethodPicker struct {
+ invokers []protocol.Invoker // Instance
+
+ weightSum int64
+ alias []int
+ prob []float64
+}
+
+func NewAliasMethodPicker(invokers []protocol.Invoker, invocation protocol.Invocation) *aliasMethodPicker {
+ am := &aliasMethodPicker{
+ invokers: invokers,
+ }
+ am.init(invocation)
+ return am
+}
+
+// Alias Method: https://en.wikipedia.org/wiki/Alias_method
+func (am *aliasMethodPicker) init(invocation protocol.Invocation) {
+ n := len(am.invokers)
+ weights := make([]int64, n)
+ am.alias = make([]int, n)
+ am.prob = make([]float64, n)
+
+ totalWeight := int64(0)
+
+ scaledProb := make([]float64, n)
+ small := make([]int, 0, n)
+ large := make([]int, 0, n)
+
+ for i, invoker := range am.invokers {
+ weight := loadbalance.GetWeight(invoker, invocation)
+ weights[i] = weight
+ totalWeight += weight
+ }
+ // when invoker weight all zero
+ if totalWeight <= 0 {
+ totalWeight = int64(1)
+ }
+ am.weightSum = totalWeight
+
+ for i, weight := range weights {
+ scaledProb[i] = float64(weight) * float64(n) / float64(totalWeight)
+ if scaledProb[i] < 1.0 {
+ small = append(small, i)
+ } else {
+ large = append(large, i)
+ }
+ }
+
+ for len(small) > 0 && len(large) > 0 {
+ l := small[len(small)-1]
+ small = small[:len(small)-1]
+ g := large[len(large)-1]
+ large = large[:len(large)-1]
+
+ am.prob[l] = scaledProb[l]
+ am.alias[l] = g
+
+ scaledProb[g] -= 1.0 - scaledProb[l]
+ if scaledProb[g] < 1.0 {
+ small = append(small, g)
+ } else {
+ large = append(large, g)
+ }
+ }
+
+ for len(large) > 0 {
+ g := large[len(large)-1]
+ large = large[:len(large)-1]
+ am.prob[g] = 1.0
+ }
+
+ for len(small) > 0 {
+ l := small[len(small)-1]
+ small = small[:len(small)-1]
+ am.prob[l] = 1.0
+ }
+}
+
+func (am *aliasMethodPicker) Pick() protocol.Invoker {
+ i := rand.Intn(len(am.invokers))
+ if rand.Float64() < am.prob[i] {
+ return am.invokers[i]
+ }
+ return am.invokers[am.alias[i]]
+}
diff --git a/cluster/loadbalance/aliasmethod/doc.go b/cluster/loadbalance/aliasmethod/doc.go
new file mode 100644
index 0000000..b3c7082
--- /dev/null
+++ b/cluster/loadbalance/aliasmethod/doc.go
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package aliasmethod implements alias-method algorithm load balance strategy.
+// Alias Method: https://en.wikipedia.org/wiki/Alias_method
+// It needs O(n) time and O(n) memory to initialize and O(1) time to generate a random number.
+package aliasmethod // weighted random with alias-method algorithm
diff --git a/cluster/loadbalance/aliasmethod/loadbalance.go b/cluster/loadbalance/aliasmethod/loadbalance.go
new file mode 100644
index 0000000..ad172ce
--- /dev/null
+++ b/cluster/loadbalance/aliasmethod/loadbalance.go
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package aliasmethod implements alias-method algorithm load balance strategy.
+package aliasmethod // weighted random with alias-method algorithm
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/common/extension"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+)
+
+func init() {
+ extension.SetLoadbalance(constant.LoadBalanceKeyAliasMethod, newWeightedRandomWithAliasMethodBalance)
+}
+
+type weightedRandomWithAliasMethodBalance struct{}
+
+// newWeightedRandomWithAliasMethodBalance returns a loadbalancer using alias-method algorithm..
+func newWeightedRandomWithAliasMethodBalance() loadbalance.LoadBalance {
+ return &weightedRandomWithAliasMethodBalance{}
+}
+
+// Select gets invoker based on interleaved weighted round robine load balancing strategy
+func (lb *weightedRandomWithAliasMethodBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {
+ count := len(invokers)
+ if count == 0 {
+ return nil
+ }
+ if count == 1 {
+ return invokers[0]
+ }
+
+ wramp := NewAliasMethodPicker(invokers, invocation)
+ return wramp.Pick()
+}
diff --git a/cluster/loadbalance/aliasmethod/loadbalance_test.go b/cluster/loadbalance/aliasmethod/loadbalance_test.go
new file mode 100644
index 0000000..dcfdf73
--- /dev/null
+++ b/cluster/loadbalance/aliasmethod/loadbalance_test.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aliasmethod
+
+import (
+ "fmt"
+ "testing"
+
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+ "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestWRAMRoundRobinSelect(t *testing.T) {
+ loadBalance := newWeightedRandomWithAliasMethodBalance()
+
+ var invokers []protocol.Invoker
+
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/org.apache.demo.HelloService",
+ constant.LocalHostValue, constant.DefaultPort))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ i := loadBalance.Select(invokers, &invocation.RPCInvocation{})
+ assert.True(t, i.GetURL().URLEqual(url))
+
+ for i := 1; i < 10; i++ {
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService", i))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ }
+ loadBalance.Select(invokers, &invocation.RPCInvocation{})
+}
+
+func TestWRAMRoundRobinByWeight(t *testing.T) {
+ loadBalance := newWeightedRandomWithAliasMethodBalance()
+
+ var invokers []protocol.Invoker
+ loop := 10
+ for i := 1; i <= loop; i++ {
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService?weight=%v", i, i))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ }
+
+ loop = (1 + loop) * loop / 2
+ selected := make(map[protocol.Invoker]int)
+
+ for i := 1; i <= loop; i++ {
+ invoker := loadBalance.Select(invokers, &invocation.RPCInvocation{})
+ selected[invoker]++
+ }
+
+ sum := 0
+ for _, value := range selected {
+ sum += value
+ }
+
+ assert.Equal(t, loop, sum)
+}
diff --git a/cluster/loadbalance/iwrr/doc.go b/cluster/loadbalance/iwrr/doc.go
new file mode 100644
index 0000000..0790fc2
--- /dev/null
+++ b/cluster/loadbalance/iwrr/doc.go
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package iwrr implements Interleaved Weighted Round Robin load balance strategy.
+// Interleaved Weighted Round Robin: https://en.wikipedia.org/wiki/Weighted_round_robin#Interleaved_WRR
+// It needs O(n log maxWeight) time and O(n) memory to initialize and O(1) time to generate a random number.
+package iwrr
diff --git a/cluster/loadbalance/iwrr/iwrr.go b/cluster/loadbalance/iwrr/iwrr.go
new file mode 100644
index 0000000..e1d78a3
--- /dev/null
+++ b/cluster/loadbalance/iwrr/iwrr.go
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package iwrr
+
+import (
+ "math/rand"
+ "sync"
+
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+)
+
+type iwrrEntry struct {
+ weight int64
+ invoker protocol.Invoker
+
+ next *iwrrEntry
+}
+
+type iwrrQueue struct {
+ head *iwrrEntry
+ tail *iwrrEntry
+}
+
+func NewIwrrQueue() *iwrrQueue {
+ return &iwrrQueue{}
+}
+
+func (item *iwrrQueue) push(entry *iwrrEntry) {
+ entry.next = nil
+ tail := item.tail
+ item.tail = entry
+ if tail == nil {
+ item.head = entry
+ } else {
+ tail.next = entry
+ }
+}
+
+func (item *iwrrQueue) pop() *iwrrEntry {
+ head := item.head
+ next := head.next
+ head.next = nil
+ item.head = next
+ if next == nil {
+ item.tail = nil
+ }
+ return head
+}
+
+func (item *iwrrQueue) empty() bool {
+ return item.head == nil
+}
+
+// InterleavedweightedRoundRobin struct
+type interleavedweightedRoundRobin struct {
+ current *iwrrQueue
+ next *iwrrQueue
+ step int64
+ mu sync.Mutex
+}
+
+func NewInterleavedweightedRoundRobin(invokers []protocol.Invoker, invocation protocol.Invocation) *interleavedweightedRoundRobin {
+ iwrrp := new(interleavedweightedRoundRobin)
+ iwrrp.current = NewIwrrQueue()
+ iwrrp.next = NewIwrrQueue()
+
+ size := uint64(len(invokers))
+ offset := rand.Uint64() % size
+ step := int64(0)
+ for idx := uint64(0); idx < size; idx++ {
+ invoker := invokers[(idx+offset)%size]
+ weight := loadbalance.GetWeight(invoker, invocation)
+ step = gcdInt(step, weight)
+ iwrrp.current.push(&iwrrEntry{
+ invoker: invoker,
+ weight: weight,
+ })
+ }
+ iwrrp.step = step
+
+ return iwrrp
+}
+
+func (iwrr *interleavedweightedRoundRobin) Pick(invocation protocol.Invocation) protocol.Invoker {
+ iwrr.mu.Lock()
+ defer iwrr.mu.Unlock()
+
+ if iwrr.current.empty() {
+ iwrr.current, iwrr.next = iwrr.next, iwrr.current
+ }
+
+ entry := iwrr.current.pop()
+ entry.weight -= iwrr.step
+
+ if entry.weight > 0 {
+ iwrr.current.push(entry)
+ } else {
+ weight := loadbalance.GetWeight(entry.invoker, invocation)
+ if weight < 0 {
+ weight = 0
+ }
+ entry.weight = weight
+ iwrr.next.push(entry)
+ }
+
+ return entry.invoker
+}
+
+func gcdInt(a, b int64) int64 {
+ for b != 0 {
+ a, b = b, a%b
+ }
+ return a
+}
diff --git a/cluster/loadbalance/iwrr/loadbalance.go b/cluster/loadbalance/iwrr/loadbalance.go
new file mode 100644
index 0000000..20f9c3c
--- /dev/null
+++ b/cluster/loadbalance/iwrr/loadbalance.go
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package iwrr
+
+import (
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/common/extension"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+)
+
+func init() {
+ extension.SetLoadbalance(constant.LoadBalanceKeyInterleavedWeightedRoundRobin, newInterleavedWeightedRoundRobinBalance)
+}
+
+type interleavedWeightedRoundRobinBalance struct{}
+
+// newInterleavedWeightedRoundRobinBalance returns a interleaved weighted round robin load balance.
+func newInterleavedWeightedRoundRobinBalance() loadbalance.LoadBalance {
+ return &interleavedWeightedRoundRobinBalance{}
+}
+
+// Select gets invoker based on interleaved weighted round robine load balancing strategy
+func (lb *interleavedWeightedRoundRobinBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {
+ count := len(invokers)
+ if count == 0 {
+ return nil
+ }
+ if count == 1 {
+ return invokers[0]
+ }
+
+ iwrrp := NewInterleavedweightedRoundRobin(invokers, invocation)
+ return iwrrp.Pick(invocation)
+}
diff --git a/cluster/loadbalance/iwrr/loadbalance_test.go b/cluster/loadbalance/iwrr/loadbalance_test.go
new file mode 100644
index 0000000..9e926ad
--- /dev/null
+++ b/cluster/loadbalance/iwrr/loadbalance_test.go
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package iwrr
+
+import (
+ "fmt"
+ "testing"
+
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+ "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestIWrrRoundRobinSelect(t *testing.T) {
+ loadBalance := newInterleavedWeightedRoundRobinBalance()
+
+ var invokers []protocol.Invoker
+
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://%s:%d/org.apache.demo.HelloService",
+ constant.LocalHostValue, constant.DefaultPort))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ i := loadBalance.Select(invokers, &invocation.RPCInvocation{})
+ assert.True(t, i.GetURL().URLEqual(url))
+
+ for i := 1; i < 10; i++ {
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService", i))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ }
+ loadBalance.Select(invokers, &invocation.RPCInvocation{})
+}
+
+func TestIWrrRoundRobinByWeight(t *testing.T) {
+ loadBalance := newInterleavedWeightedRoundRobinBalance()
+
+ var invokers []protocol.Invoker
+ loop := 10
+ for i := 1; i <= loop; i++ {
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService?weight=%v", i, i))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ }
+
+ loop = (1 + loop) * loop / 2
+ selected := make(map[protocol.Invoker]int)
+
+ for i := 1; i <= loop; i++ {
+ invoker := loadBalance.Select(invokers, &invocation.RPCInvocation{})
+ selected[invoker]++
+ }
+
+ sum := 0
+ for _, value := range selected {
+ sum += value
+ }
+
+ assert.Equal(t, loop, sum)
+}
diff --git a/cluster/loadbalance/loadbalance_benchmarks_test.go b/cluster/loadbalance/loadbalance_benchmarks_test.go
new file mode 100644
index 0000000..fa89ddd
--- /dev/null
+++ b/cluster/loadbalance/loadbalance_benchmarks_test.go
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package loadbalance_test
+
+import (
+ "fmt"
+ "testing"
+
+ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/aliasmethod"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/consistenthashing"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/iwrr"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/leastactive"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/p2c"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/random"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/ringhash"
+ _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/roundrobin"
+ "dubbo.apache.org/dubbo-go/v3/common"
+ "dubbo.apache.org/dubbo-go/v3/common/constant"
+ "dubbo.apache.org/dubbo-go/v3/common/extension"
+ "dubbo.apache.org/dubbo-go/v3/protocol"
+ "dubbo.apache.org/dubbo-go/v3/protocol/invocation"
+)
+
+func Generate() []protocol.Invoker {
+ var invokers []protocol.Invoker
+ for i := 1; i < 256; i++ {
+ url, _ := common.NewURL(fmt.Sprintf("dubbo://192.168.1.%v:20000/org.apache.demo.HelloService", i))
+ invokers = append(invokers, protocol.NewBaseInvoker(url))
+ }
+ return invokers
+}
+
+func Benchloadbalance(b *testing.B, lb loadbalance.LoadBalance) {
+ b.Helper()
+ invokers := Generate()
+ b.ReportAllocs()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ lb.Select(invokers, &invocation.RPCInvocation{})
+ }
+}
+
+func BenchmarkRoudrobinLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyRoundRobin))
+}
+
+func BenchmarkLeastativeLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyLeastActive))
+}
+
+func BenchmarkConsistenthashingLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyConsistentHashing))
+}
+
+func BenchmarkP2CLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyP2C))
+}
+
+func BenchmarkInterleavedWeightedRoundRobinLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyInterleavedWeightedRoundRobin))
+}
+
+func BenchmarkRandomLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyRandom))
+}
+
+func BenchmarkAliasMethodLoadbalance(b *testing.B) {
+ Benchloadbalance(b, extension.GetLoadbalance(constant.LoadBalanceKeyAliasMethod))
+}
diff --git a/common/constant/loadbalance.go b/common/constant/loadbalance.go
index dde8443..c30a706 100644
--- a/common/constant/loadbalance.go
+++ b/common/constant/loadbalance.go
@@ -18,10 +18,12 @@
package constant
const (
- LoadBalanceKeyConsistentHashing = "consistenthashing"
- LoadBalanceKeyLeastActive = "leastactive"
- LoadBalanceKeyRandom = "random"
- LoadBalanceKeyRoundRobin = "roundrobin"
- LoadBalanceKeyP2C = "p2c"
- LoadXDSRingHash = "xdsringhash"
+ LoadBalanceKeyConsistentHashing = "consistenthashing"
+ LoadBalanceKeyLeastActive = "leastactive"
+ LoadBalanceKeyRandom = "random"
+ LoadBalanceKeyRoundRobin = "roundrobin"
+ LoadBalanceKeyP2C = "p2c"
+ LoadXDSRingHash = "xdsringhash"
+ LoadBalanceKeyInterleavedWeightedRoundRobin = "interleavedweightedroundrobin"
+ LoadBalanceKeyAliasMethod = "aliasmethod"
)