golb

package module
v0.0.0-...-f80139c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2020 License: MIT Imports: 9 Imported by: 0

README

golb

Doc MIT licensed codecov Build Status

NGINX-like load-balancing method implementation in Go

Introduce

Package golb provides NGINX-like load balancing implementation in Go which references NGINX implementation. The package only provides load balancing methods without network operations and management of connections to peer servers, and is safe for concurrent use by multiple goroutines.

You can also read related NGINX doc fist.

Supported load balancing methods are:

round-robin: Picks a peer server in turn.

least-conn: Picks a peer server which has the least number of connections.

hash: Applies crc32 hash to  a key provided by caller and maps to a peer server. 
The same key will always be mapped to the same peer sever unless the peer doesn't meet other requirements, 
such as reaches the max_conns limitation.

consistent hash: Picks a peer as hash, and ensures that  a few keys will be remapped to different servers 
when a server is added to or removed.

ip-hash: Picks a peer as hash, but uses ip as key, specially  uses the first three bytes of ipv4 address  
and uses total of ipv6 address.

random: Picks a peer at random.

Supported peer server parameters are:

weight: The weight of peer server.

max_conns: Limits the maximum number of simultaneous active connections to the peer server.

max_fails, fail_timeout: Sets the number of unsuccessful attempts to communicate with the server that 
should happen in the duration set by the fail_timeout parameter to consider the  server unavailable for 
a duration also set by the fail_timeout parameter.

See godoc in details.

Install

go get -u github.com/longzhiri/golb

Usage

var peers []*Peer
peers = append(peers, NewPeer("10.11.11.10", 1, 0, 0, 100))
peers = append(peers, NewPeer("10.11.11.11", 5, 3, 5*time.Second, 100))
peers = append(peers, NewPeer("10.11.11.12", 0, 0, 0, 0))

// Instantiates a round-robin LB.
rr := NewRoundRobinLB(peers)
peer, err := rr.GetPeer()
if err == nil {
	// Do something.

	// Free the peer's connection with failed.
	rr.FreePeerConnection(peer, true)
}
rr.RemovePeer("10.11.11.12") // Remove the peer
rr.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a least-conn LB
lc := NewLeastConnLB(peers)
peer, err = lc.GetPeer()
if err == nil {
	lc.FreePeerConnection(peer, true)
}
lc.RemovePeer("10.11.11.12")
lc.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a hash LB
hl := NewHashLB(peers)
peer, err = hl.GetPeer([]byte("key"))
if err == nil {
	hl.FreePeerConnection(peer, true)
}
hl.RemovePeer("10.11.11.12")
hl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a consistent hash LB
chl := NewConsistentHashLB(peers)
peer, err = chl.GetPeer([]byte("key"))
if err == nil {
	chl.FreePeerConnection(peer, true)
}
chl.RemovePeer("10.11.11.12")
chl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a ip-hash LB
ih := NewIpHashLB(peers)
peer, err = ih.GetPeer(net.ParseIP("1.1.1.1"), false)
if err == nil {
	ih.FreePeerConnection(peer, true)
}
ih.RemovePeer("10.11.11.12")
ih.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a least-conn LB
rl := NewRandomLB(peers)
peer, err = rl.GetPeer()
if err == nil {
	rl.FreePeerConnection(peer, true)
}
rl.RemovePeer("10.11.11.12")
rl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

License

The MIT License (MIT)

Documentation

Overview

Package golb provides NGINX-like load balancing implementation in Go which references NGINX implementation. The package only provides load balancing methods without network operations and management of connections to peer servers, and is safe for concurrent use by multiple goroutines.

You can also read related NGINX doc(http://nginx.org/en/docs/http/ngx_http_upstream_module.html) fist.

Supported load balancing methods are:

round-robin: Picks a peer server in turn.
least-conn: Picks a peer server which has the least number of connections.
hash: Applies crc32 hash to  a key provided by caller and maps to a peer server. The same key will always be mapped to the same peer sever unless the peer doesn't
meet other requirements, such as reaches the max_conns limitation.
consistent hash: Picks a peer as hash, and ensures that  a few keys will be remapped to different servers when a server is added to or removed.
ip-hash: Picks a peer as hash, but uses ip as key, specially  uses the first three bytes of ipv4 address  and uses total of ipv6 address.
random: Picks a peer at random.

Supported peer server parameters are:

weight: The weight of peer server.
max_conns: Limits the maximum number of simultaneous active connections to the peer server.
max_fails, fail_timeout: Sets the number of unsuccessful attempts to communicate with the server that should happen in the duration set by the fail_timeout
parameter to consider the server unavailable for a duration also set by the fail_timeout parameter.

Examples:

var peers []*Peer
peers = append(peers, NewPeer("10.11.11.10", 1, 0, 0, 100))
peers = append(peers, NewPeer("10.11.11.11", 5, 3, 5*time.Second, 100))
peers = append(peers, NewPeer("10.11.11.12", 0, 0, 0, 0))

// Instantiates a round-robin LB.
rr := NewRoundRobinLB(peers)
peer, err := rr.GetPeer()
if err == nil {
	// Do something.

	// Free the peer's connection with failed.
	rr.FreePeerConnection(peer, true)
}
rr.RemovePeer("10.11.11.12") // Remove the peer
rr.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a least-conn LB
lc := NewLeastConnLB(peers)
peer, err = lc.GetPeer()
if err == nil {
	lc.FreePeerConnection(peer, true)
}
lc.RemovePeer("10.11.11.12")
lc.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a hash LB
hl := NewHashLB(peers)
peer, err = hl.GetPeer([]byte("key"))
if err == nil {
	hl.FreePeerConnection(peer, true)
}
hl.RemovePeer("10.11.11.12")
hl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a consistent hash LB
chl := NewConsistentHashLB(peers)
peer, err = chl.GetPeer([]byte("key"))
if err == nil {
	chl.FreePeerConnection(peer, true)
}
chl.RemovePeer("10.11.11.12")
chl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a ip-hash LB
ih := NewIpHashLB(peers)
peer, err = ih.GetPeer(net.ParseIP("1.1.1.1"), false)
if err == nil {
	ih.FreePeerConnection(peer, true)
}
ih.RemovePeer("10.11.11.12")
ih.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

// Instantiates a least-conn LB
rl := NewRandomLB(peers)
peer, err = rl.GetPeer()
if err == nil {
	rl.FreePeerConnection(peer, true)
}
rl.RemovePeer("10.11.11.12")
rl.AddPeer(NewPeer("10.11.11.13", 1, 3, 10*time.Second, 0))

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPeerAlreadyExistInLB = errors.New("the peer already exists")
	ErrPeerNotExistInLB     = errors.New("the peer doesn't exists")
	ErrNoAvailablePeerInLB  = errors.New("no available peer found")
	ErrInvalidIpAddr        = errors.New("invalid ip address")
)

Functions

This section is empty.

Types

type ConsistentHashLB

type ConsistentHashLB struct {
	RoundRobinLB
	// contains filtered or unexported fields
}

ConsistentHashLB implements the consistent-hash method.

func NewConsistentHashLB

func NewConsistentHashLB(peers []*Peer) *ConsistentHashLB

NewConsistentHashLB instantiates a ConsistentHashLB with the peers for the consistent-hash load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*ConsistentHashLB) AddPeer

func (chl *ConsistentHashLB) AddPeer(peer *Peer) (*Peer, error)

AddPeer adds a peer dynamically, the peer will be copied into the LB, so is safe to modify it after the calling.

func (*ConsistentHashLB) GetPeer

func (chl *ConsistentHashLB) GetPeer(key []byte) (*Peer, error)

GetPeer picks a peer by the consistent-hash method, a error will be returned if failed. It will fallback to the round-robin method if no available peers are found after limited times are checked.

func (*ConsistentHashLB) RemovePeer

func (chl *ConsistentHashLB) RemovePeer(address string) error

RemovePeer removes a peer dynamically.

type HashLB

type HashLB struct {
	RoundRobinLB
}

HashLB implements the hash method.

func NewHashLB

func NewHashLB(peers []*Peer) *HashLB

NewHashLB instantiates a HashLB with the peers for the hash load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*HashLB) GetPeer

func (hl *HashLB) GetPeer(key []byte) (*Peer, error)

GetPeer picks a peer by the hash method, a error will be returned if failed. It will fallback to the round-robin method if no available peers are found after limited times are checked.

type IpHashLB

type IpHashLB struct {
	RoundRobinLB
}

IpHashLB implements the ip-hash method.

func NewIpHashLB

func NewIpHashLB(peers []*Peer) *IpHashLB

NewIpHashLB instantiates a IpHashLB with the peers for the ip-hash load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*IpHashLB) GetPeer

func (ihl *IpHashLB) GetPeer(ip net.IP, ipv6 bool) (*Peer, error)

GetPeer picks a peer by the ip-hash method, a error will be returned if failed. It will fallback to round-robin method if no available peers are found after limited times are checked. The ipv6 must be set since the ip can't tell whether is ipv6.

type LeastConnLB

type LeastConnLB struct {
	RoundRobinLB
}

LeastConnLB implements the least-conn method.

func NewLeastConnLB

func NewLeastConnLB(peers []*Peer) *LeastConnLB

NewLeastConnLB instantiates a LeastConnLB with the peers for the least-conn load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*LeastConnLB) GetPeer

func (lc *LeastConnLB) GetPeer() (*Peer, error)

GetPeer picks a peer by the least-conn method, a error will be returned if failed. It will then picks by the round-robin method if multiple least-conn peers are found.

type Peer

type Peer struct {
	// contains filtered or unexported fields
}

Peer represents a backend or a proxied server or a node.

func NewPeer

func NewPeer(address string, weight int, maxFails int, failTimeout time.Duration, maxConns int) *Peer

NewPeer creates a new peer.

address: Peer's address, can be anything defined by uses, such as tcp/udp address (ip:port), unix domain socket addr(), but each peer's address must be unique.

weight: The weight of the peer server, it will be set to 1 if weight is passed less than 0.

maxFails, failTimeout: Sets the number of unsuccessful attempts to communicate with the server that should happen in the duration set by the failTimeout parameter to consider the server unavailable for a duration also set by the failTimeout parameter. The zero value of maxFails disables the accounting of attempts.

maxConns: Limits the maximum number of simultaneous active connections to the peer server, the zero value disables the limitation.

func (*Peer) Address

func (p *Peer) Address() string

func (*Peer) FailTimeout

func (p *Peer) FailTimeout() time.Duration

func (*Peer) MaxConns

func (p *Peer) MaxConns() int

func (*Peer) MaxFails

func (p *Peer) MaxFails() int

func (*Peer) Weight

func (p *Peer) Weight() int

type RandomLB

type RandomLB struct {
	RoundRobinLB
	// contains filtered or unexported fields
}

IpHashLB implements the random method.

func NewRandomLB

func NewRandomLB(peers []*Peer) *RandomLB

NewRandomLB instantiates a RandomLB with the peers for the random load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*RandomLB) GetPeer

func (rl *RandomLB) GetPeer() (*Peer, error)

GetPeer picks a peer by the random method, a error will be returned if failed. It will fallback to the round-robin method if no available peers are found after limited times are checked.

type RoundRobinLB

type RoundRobinLB struct {
	// contains filtered or unexported fields
}

RoundRobinLB implements the round-robin method.

func NewRoundRobinLB

func NewRoundRobinLB(peers []*Peer) *RoundRobinLB

NewRoundRobinLB instantiates a RoundRobinLB with the peers for the round-robin load balancing method using. The peers will be copied into the LB, so you can still modify the peers without influencing the LB after the calling. The peer which has the same address with prior peer in the slice will be ignored, so ensure each peer's address must be unique.

func (*RoundRobinLB) AddPeer

func (rr *RoundRobinLB) AddPeer(peer *Peer) (*Peer, error)

AddPeer adds a peer dynamically, the peer will be copied into the LB, so is safe to modify it after the calling.

func (*RoundRobinLB) FreePeerConnection

func (rr *RoundRobinLB) FreePeerConnection(peer *Peer, connFailed bool)

FreePeerConnection notifies to reduce the conns and to adjust the fails according the connFailed.

func (*RoundRobinLB) GetPeer

func (rr *RoundRobinLB) GetPeer() (*Peer, error)

GetPeer picks a peer by the round-robin method, a error will be returned if failed.

func (*RoundRobinLB) RemovePeer

func (rr *RoundRobinLB) RemovePeer(address string) error

RemovePeer removes a peer dynamically.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL