This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/main by this push:
     new b6456598b Add interleaved weighted round-robin and alias-method 
loadbalancer (#2606)
b6456598b is described below

commit b6456598b000687318c30ea8d9a630fdba474817
Author: Nick Xu <[email protected]>
AuthorDate: Fri Mar 8 11:59:16 2024 +0800

    Add interleaved weighted round-robin and alias-method loadbalancer (#2606)
---
 cluster/loadbalance/aliasmethod/alias_method.go    | 113 ++++++++++++++++++
 .../loadbalance/aliasmethod/doc.go                 |  14 +--
 cluster/loadbalance/aliasmethod/loadbalance.go     |  51 ++++++++
 .../loadbalance/aliasmethod/loadbalance_test.go    |  73 ++++++++++++
 .../loadbalance/iwrr/doc.go                        |  14 +--
 cluster/loadbalance/iwrr/iwrr.go                   | 130 +++++++++++++++++++++
 cluster/loadbalance/iwrr/loadbalance.go            |  50 ++++++++
 cluster/loadbalance/iwrr/loadbalance_test.go       |  73 ++++++++++++
 cluster/loadbalance/loadbalance_benchmarks_test.go |  85 ++++++++++++++
 common/constant/loadbalance.go                     |  14 ++-
 10 files changed, 591 insertions(+), 26 deletions(-)

diff --git a/cluster/loadbalance/aliasmethod/alias_method.go 
b/cluster/loadbalance/aliasmethod/alias_method.go
new file mode 100644
index 000000000..10c49cd5f
--- /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/common/constant/loadbalance.go 
b/cluster/loadbalance/aliasmethod/doc.go
similarity index 71%
copy from common/constant/loadbalance.go
copy to cluster/loadbalance/aliasmethod/doc.go
index dde844337..b3c708217 100644
--- a/common/constant/loadbalance.go
+++ b/cluster/loadbalance/aliasmethod/doc.go
@@ -15,13 +15,7 @@
  * limitations under the License.
  */
 
-package constant
-
-const (
-       LoadBalanceKeyConsistentHashing = "consistenthashing"
-       LoadBalanceKeyLeastActive       = "leastactive"
-       LoadBalanceKeyRandom            = "random"
-       LoadBalanceKeyRoundRobin        = "roundrobin"
-       LoadBalanceKeyP2C               = "p2c"
-       LoadXDSRingHash                 = "xdsringhash"
-)
+// 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 000000000..ad172ce4c
--- /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 000000000..dcfdf7357
--- /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/common/constant/loadbalance.go b/cluster/loadbalance/iwrr/doc.go
similarity index 71%
copy from common/constant/loadbalance.go
copy to cluster/loadbalance/iwrr/doc.go
index dde844337..0790fc2d3 100644
--- a/common/constant/loadbalance.go
+++ b/cluster/loadbalance/iwrr/doc.go
@@ -15,13 +15,7 @@
  * limitations under the License.
  */
 
-package constant
-
-const (
-       LoadBalanceKeyConsistentHashing = "consistenthashing"
-       LoadBalanceKeyLeastActive       = "leastactive"
-       LoadBalanceKeyRandom            = "random"
-       LoadBalanceKeyRoundRobin        = "roundrobin"
-       LoadBalanceKeyP2C               = "p2c"
-       LoadXDSRingHash                 = "xdsringhash"
-)
+// 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 000000000..e1d78a370
--- /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 000000000..20f9c3c20
--- /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 000000000..9e926adf3
--- /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 000000000..fa89ddd5c
--- /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 dde844337..c30a7062d 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"
 )

Reply via email to