loadbalancer

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2023 License: Apache-2.0 Imports: 6 Imported by: 5

README

Go LoadBalancer Build Status GoDoc License

Require Go 1.21+.

Install

$ go get -u github.com/xgfone/go-loadbalancer

Example

Mini API Gateway
package main

import (
	"encoding/json"
	"flag"
	"net/http"

	"github.com/xgfone/go-loadbalancer"
	"github.com/xgfone/go-loadbalancer/balancer"
	"github.com/xgfone/go-loadbalancer/forwarder"
	"github.com/xgfone/go-loadbalancer/httpx"
)

var listenAddr = flag.String("listenaddr", ":80", "The address that api gateway listens on.")

func main() {
	flag.Parse()
	http.HandleFunc("/admin/route", registerRouteHandler)
	_ = http.ListenAndServe(*listenAddr, nil)
}

func registerRouteHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var req struct {
		// Route Matcher
		Path   string `json:"path" validate:"required"`
		Method string `json:"method" validate:"required"`

		// Upstream Endpoints
		Upstream struct {
			ForwardPolicy string `json:"forwardPolicy" default:"weight_random"`
			Servers       []struct {
				Host   string `json:"host" validate:"host"`
				Port   uint16 `json:"port" validate:"ranger(1,65535)"`
				Weight int    `json:"weight" default:"1" validate:"min(1)"`
			} `json:"servers"`
		} `json:"upstream"`
	}

	// Notice: here we don't validate whether the values are valid.
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "invalid request route paramenter: "+err.Error(), 400)
		return
	}

	// Build the upstream backend servers.
	static := loadbalancer.NewStaticWithCap(len(req.Upstream.Servers))
	for _, server := range req.Upstream.Servers {
		c := httpx.Config{Host: server.Host, Port: server.Port, Weight: server.Weight}
		static.Append(c.NewEndpoint())
	}

	// Build the loadbalancer forwarder.
	balancer := balancer.Get(req.Upstream.ForwardPolicy) // not check it is nil
	forwarder := forwarder.New(req.Method+"@"+req.Path, balancer, static)

	// Register the route and forward the request to forwarder.
	http.HandleFunc(req.Path, func(w http.ResponseWriter, r *http.Request) {
		if r.Method != req.Method {
			w.WriteHeader(http.StatusMethodNotAllowed)
		} else {
			// You can use forwarder.ForwardHTTP to control the request and response.
			forwarder.ServeHTTP(w, r)
		}
	})
}
# Run the mini API-Gateway on the host 192.168.1.10
$ nohup go run main.go &

# Add the route
# Notice: remove the characters from // to the line end.
$ curl -XPOST http://127.0.0.1/admin/route -H 'Content-Type: application/json' -d '
{
    "path": "/path",
    "method": "GET",
    "upstream": {
        "forwardPolicy": "weight_round_robin",
        "servers": [
            {"host": "192.168.1.11", "port": 80, "weight": 10}, // 33.3% requests
            {"host": "192.168.1.12", "port": 80, "weight": 20}  // 66.7% requests
        ]
    }
}'

# Access the backend servers by the mini API-Gateway:
# 2/6(33.3%) requests -> 192.168.1.11
# 4/6(66.7%) requests -> 192.168.1.12
$ curl http://192.168.1.10/path
192.168.1.11/backend/path

$ curl http://192.168.1.10/path
192.168.1.12/backend/path

$ curl http://192.168.1.10/path
192.168.1.12/backend/path

$ curl http://192.168.1.10/path
192.168.1.11/backend/path

$ curl http://192.168.1.10/path
192.168.1.12/backend/path

$ curl http://192.168.1.10/path
192.168.1.12/backend/path

Documentation

Overview

Package loadbalancer provides some common functions.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoAvailableEndpoints = errors.New("no available endpoints")

ErrNoAvailableEndpoints is used to represents no available endpoints.

View Source
var None = new(Static)

None represents a static without endpoints.

View Source
var SortEndpoints func(Endpoints) = sortEndpoints

SortEndpoints is used to sort a set of the endpoints.

For the default implementation, sort them by the id from small to big.

Functions

func Release added in v0.8.0

func Release(eps *Static)

Release releases the static endpoints back into the pool.

Types

type AtomicStatic added in v0.9.0

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

AtomicStatic is a atomic static discovery.

func NewAtomicStatic added in v0.9.0

func NewAtomicStatic(static *Static) *AtomicStatic

NewAtomicStatic a new atomic static.

func (*AtomicStatic) Discover added in v0.9.0

func (s *AtomicStatic) Discover() *Static

Discover implements the interface Discovery.

func (*AtomicStatic) Set added in v0.9.0

func (s *AtomicStatic) Set(new *Static)

Set sets the static to new.

func (*AtomicStatic) Swap added in v0.9.0

func (s *AtomicStatic) Swap(new *Static) (old *Static)

Swap swap the old static with the new.

type Discovery added in v0.8.0

type Discovery interface {
	Discover() *Static
}

Discovery is used to discover the endpoints.

type DiscoveryFunc added in v0.8.0

type DiscoveryFunc func() *Static

DiscoveryFunc is a discovery function.

func (DiscoveryFunc) Discover added in v0.8.0

func (f DiscoveryFunc) Discover() *Static

Discover implements the interface Discovery.

type Endpoint

type Endpoint interface {
	LoadBalancer
	ID() string
}

Endpoint represents a backend endpoint.

type Endpoints

type Endpoints []Endpoint

Endpoints represents a group of the endpoints.

func (Endpoints) Contains

func (eps Endpoints) Contains(epid string) bool

Contains reports whether the endpoints contains the endpoint indicated by the id.

func (Endpoints) Discover added in v0.8.0

func (eps Endpoints) Discover() *Static

Discover implements the interface Discovery, which is just used to test in general.

func (Endpoints) Len

func (eps Endpoints) Len() (n int)

Len return the number of all the endpoints,

type LoadBalancer

type LoadBalancer interface {
	Serve(ctx context.Context, req any) (resp any, err error)
}

LoadBalancer is a load balancer to serve the request.

type RetryError added in v0.7.0

type RetryError interface {
	Retry() bool
	error
}

RetryError represents a retry error.

func NewRetryError added in v0.7.0

func NewRetryError(retry bool, err error) RetryError

NewRetryError returns a new retry error, but returns nil instead if err is nil.

type ServeFunc added in v0.8.0

type ServeFunc func(ctx context.Context, req any) (resp any, err error)

ServeFunc is the loadbalancer serve function.

func (ServeFunc) Serve added in v0.8.0

func (f ServeFunc) Serve(ctx context.Context, req any) (any, error)

Serve implements the interface LoadBalancer.

type Static added in v0.8.0

type Static struct{ Endpoints }

Static is used to wrap a set of endpoints.

func Acquire added in v0.8.0

func Acquire(expectedMaxCap int) *Static

Acquire acquires a preallocated zero-length endpoints from the pool.

func NewStatic added in v0.8.0

func NewStatic(eps Endpoints) *Static

NewStatic returns a new static with the endpoints.

func NewStaticWithCap added in v0.9.0

func NewStaticWithCap(n int) *Static

NewStaticWithCap returns a new static with the 0-len and n-cap endpoints.

func (*Static) Append added in v0.8.0

func (s *Static) Append(eps ...Endpoint)

Append appends the endpoints.

func (*Static) Discover added in v0.8.0

func (s *Static) Discover() *Static

Discover returns itself, which implements the interface Discovery.

func (*Static) Len added in v0.8.0

func (s *Static) Len() int

Len returns the number of the endpoints.

Directories

Path Synopsis
Package balancer provides a balancer interface and builder, which is used to forward the request to one of the backend endpoints by the specific policy.
Package balancer provides a balancer interface and builder, which is used to forward the request to one of the backend endpoints by the specific policy.
consistenthash
Package consistenthash provides a balancer based on the consistent hash.
Package consistenthash provides a balancer based on the consistent hash.
leastconn
Package leastconn provides a balancer based on the least connections.
Package leastconn provides a balancer based on the least connections.
random
Package random provides a balancer based on the random.
Package random provides a balancer based on the random.
retry
Package retry provides a retry balancer, which will retry the rest endpoints when failing to forward the request.
Package retry provides a retry balancer, which will retry the rest endpoints when failing to forward the request.
roundrobin
Package roundrobin provides a balancer based on the roundrobin.
Package roundrobin provides a balancer based on the roundrobin.
sourceiphash
Package sourceiphash provides a balancer based on the source-ip hash.
Package sourceiphash provides a balancer based on the source-ip hash.
Package endpoint provides some auxiliary functions about endpoint.
Package endpoint provides some auxiliary functions about endpoint.
Package forwarder provides a loadbalance forwarder.
Package forwarder provides a loadbalance forwarder.
Package httpx provides some functions about http.
Package httpx provides some functions about http.
internal

Jump to

Keyboard shortcuts

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