Load Balancer Strategy

Suppose you are implementing the load balancing strategy for a nginx-liked web server. Given a list of ip [1, 2, 3], return the next round-robined result.

Basic Version

At the first glance, we can use a counter to track the number of the next ip.

package main

import "fmt"

func main() {
	ips := []int{1, 2, 3}
	lb := NewLB(ips)
	for i := 0; i < 10; i++ {
		fmt.Printf("%v\n", lb.Next())
	}
}

type LB struct {
	ips   []int
	count int
	size  int
}

func NewLB(ips []int) *LB {
	return &LB{
		ips:   ips,
		count: 0,
		size:  len(ips),
	}
}

func (lb *LB) Next() int {
	lb.count += 1
	lb.count %= lb.size
	return lb.ips[lb.count]
}

func (lb *LB) Next1() int {
	lb.count += 1
	if lb.count == lb.size {
		lb.count = 0
	}
	return lb.ips[lb.count]
}
package main

import (
	"fmt"
	"sync"
)

func main() {
	ips := []int{1, 2, 3}
	lb := NewLB(ips)
	wg := &sync.WaitGroup{}
	for j := 0; j < 3; j++ {
		wg.Add(1)
		go func() {
			for i := 0; i < 10; i++ {
				fmt.Printf("%v\n", lb.Next())
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

type LB struct {
	ips   []int
	count int
	size  int
	m     *sync.Mutex
}

func NewLB(ips []int) *LB {
	return &LB{
		ips:   ips,
		count: 0,
		size:  len(ips),
		m:     &sync.Mutex{},
	}
}

func (lb *LB) Next() int {
	lb.m.Lock()
	defer lb.m.Unlock()

	lb.count += 1
	if lb.count == lb.size {
		lb.count = 0
	}
	return lb.ips[lb.count]
}

Concurrency Version

We could use a mutex lock to protect the counter.

package main

import (
	"fmt"
	"sync"
)

func main() {
	ips := []int{1, 2, 3}
	lb := NewLB(ips)
	wg := &sync.WaitGroup{}
	for j := 0; j < 3; j++ {
		wg.Add(1)
		go func() {
			for i := 0; i < 10; i++ {
				fmt.Printf("%v\n", lb.Next())
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

type LB struct {
	ips   []int
	count int
	size  int
	m     *sync.Mutex
}

func NewLB(ips []int) *LB {
	return &LB{
		ips:   ips,
		count: 0,
		size:  len(ips),
		m:     &sync.Mutex{},
	}
}

func (lb *LB) Next() int {
	lb.m.Lock()
	defer lb.m.Unlock()

	lb.count += 1
	if lb.count == lb.size {
		lb.count = 0
	}
	return lb.ips[lb.count]
}

Grouped Ips

Follow-Up: Suppose ips are grouped. e.g. A: [1, 2, 3], B: [1, 4, 5]. Get the next round-robined result for the specified group combination. Input A means selecting from the group A. Input B means select from the group B. Input AB means select from the intersection of group A and B. Empty means select from all ips.

results matching ""

    No results matching ""