proxykit

package
v1.16.0 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2025 License: MIT Imports: 14 Imported by: 0

README

Proxy Kit

A production-grade reverse proxy library implemented in Go. It not only provides high performance and multiple load balancing strategies, but also supports dynamic route management, allowing you to add or remove backend servers at runtime via API — without restarting the service.


Core Features

  • Dynamic Service Discovery: Add or remove backend nodes in real-time through HTTP APIs.
  • High Performance Core: Built on net/http/httputil with deeply optimized connection pooling for effortless high-concurrency handling.
  • Rich Load Balancing Strategies: Includes Round Robin, The Least Connections, and IP Hash.
  • Active Health Checks: Automatically detects and isolates unhealthy nodes, and brings them back online once they recover.
  • Multi-route Support: Distribute traffic to different backend groups based on path prefixes.

Example of Usage

package main

import (
    "log"
    "net/http"
    "time"
    "github.com/go-dev-frame/sponge/pkg/proxykit"
)

func main() {
    prefixPath := "/proxy/"

    // 1. Create the route manager
    manager := proxykit.NewRouteManager()

    // 2. Initialize backend targets
    initialTargets := []string{"http://localhost:8081", "http://localhost:8082"}
    backends, _ := proxykit.ParseBackends(prefixPath, initialTargets)
    proxykit.StartHealthChecks(backends, proxykit.HealthCheckConfig{Interval: 5 * time.Second})
    balancer := proxykit.NewRoundRobin(backends)

    // Register route
    apiRoute, err := manager.AddRoute(prefixPath, balancer)
    if err != nil {
        log.Fatalf("Could not add initial route: %v", err)
    }

    // 3. Build standard library mux
    mux := http.NewServeMux()

    // 4. Register proxy handler (same as gin.Any)
    mux.Handle(prefixPath, apiRoute.Proxy)

    // 5. Management API (corresponds to /endpoints/...)
    mux.HandleFunc("/endpoints/add", manager.HandleAddBackends)
    mux.HandleFunc("/endpoints/remove", manager.HandleRemoveBackends)
    mux.HandleFunc("/endpoints/list", manager.HandleListBackends)
    mux.HandleFunc("/endpoints", manager.HandleGetBackend)

    // 6. Other normal routes
    mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(`{"message": "pong"}`))
    })

    // 7. Start HTTP server
    log.Println("HTTP server with dynamic proxy started on http://localhost:8080")
    log.Printf("Proxying requests from %s*\n", prefixPath)
    log.Println("Management API available at /endpoints/*")

    err = http.ListenAndServe(":8080", mux)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

Management API Guide

After the proxy is started, you can manage backend services dynamically via the following APIs.

1. List all backends

Retrieve all backend nodes and their health status for the given route.

  • GET /endpoints/list?prefixPath=/api/
{
  "prefixPath": "/api/",
  "targets": [
    {"target": "http://localhost:8081", "healthy": true}
  ]
}
2. Add backend nodes

Dynamically scale out. New nodes will automatically enter the health check loop and start receiving traffic.

  • POST /endpoints/add

  • Body:

    {
      "prefixPath": "/api/",
      "targets": ["http://localhost:8083", "http://localhost:8084"]
    }
    
3. Remove backend nodes

Dynamically scale in. Health checks for removed nodes will stop automatically.

  • POST /endpoints/remove

  • Body:

    {
      "prefixPath": "/api/",
      "targets": ["http://localhost:8081"]
    }
    
4. Inspect a single backend node
  • GET /endpoints?prefixPath=/api/&target=http://localhost:8082
{
  "target": "http://localhost:8082",
  "healthy": true
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoHealthyBackends = errors.New("no healthy backends available")
)

Functions

func AnyRelativePath

func AnyRelativePath(prefixPath string) string

func Chain

func Chain(h http.Handler, middlewares ...Middleware) http.Handler

Chain links multiple middlewares together to form a single http.Handler.

func DefaultTransport

func DefaultTransport() *http.Transport

DefaultTransport returns a http.Transport optimized for reverse proxy usage.

func SetLogger

func SetLogger(l *zap.Logger)

func StartHealthChecks

func StartHealthChecks(backends []*Backend, config HealthCheckConfig)

StartHealthChecks initiate backend health check for the backend server pool.

Types

type Backend

type Backend struct {
	URL *url.URL
	// contains filtered or unexported fields
}

Backend encapsulates the backend server information.

func NewBackend

func NewBackend(prefixPath string, u *url.URL) *Backend

NewBackend creates a new Backend instance.

func ParseBackends

func ParseBackends(prefixPath string, targets []string) ([]*Backend, error)

ParseBackends helper function: converts a list of URL strings into []*Backend

func (*Backend) DecrementActiveConns

func (b *Backend) DecrementActiveConns()

func (*Backend) GetActiveConns

func (b *Backend) GetActiveConns() int64

func (*Backend) IncrementActiveConns

func (b *Backend) IncrementActiveConns()

func (*Backend) IsHealthy

func (b *Backend) IsHealthy() bool

func (*Backend) SetHealthy

func (b *Backend) SetHealthy(healthy bool)

func (*Backend) StopHealthCheck

func (b *Backend) StopHealthCheck()

StopHealthCheck stops the health check goroutine associated with this backend.

type Balancer

type Balancer interface {
	Next(r *http.Request) (*Backend, error)
	GetBackends() []*Backend
	AddBackend(b *Backend)
	RemoveBackend(b *Backend)
}

Balancer is an interface that must be implemented for all load balancing strategies.

type HealthCheckConfig

type HealthCheckConfig struct {
	Interval time.Duration `json:"interval"`
	Timeout  time.Duration `json:"timeout"`
}

HealthCheckConfig defined the configuration for health check.

type IPHash

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

func NewIPHash

func NewIPHash(backends []*Backend) *IPHash

func (*IPHash) AddBackend

func (h *IPHash) AddBackend(b *Backend)

func (*IPHash) GetBackends

func (h *IPHash) GetBackends() []*Backend

func (*IPHash) Next

func (h *IPHash) Next(r *http.Request) (*Backend, error)

func (*IPHash) RemoveBackend

func (h *IPHash) RemoveBackend(b *Backend)

type LeastConnections

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

func NewLeastConnections

func NewLeastConnections(backends []*Backend) *LeastConnections

func (*LeastConnections) AddBackend

func (lc *LeastConnections) AddBackend(b *Backend)

func (*LeastConnections) GetBackends

func (lc *LeastConnections) GetBackends() []*Backend

func (*LeastConnections) Next

func (lc *LeastConnections) Next(_ *http.Request) (*Backend, error)

func (*LeastConnections) RemoveBackend

func (lc *LeastConnections) RemoveBackend(b *Backend)

type ManagementRequest

type ManagementRequest struct {
	PrefixPath  string            `json:"prefixPath"`
	Targets     []string          `json:"targets"`
	HealthCheck HealthCheckConfig `json:"healthCheck"`
}

ManagementRequest is for the management API.

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware is a function that takes a http.Handler and returns a http.Handler, used to build a middleware chain.

type Proxy

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

Proxy is a reverse proxy that implements the http.Handler interface.

func NewProxy

func NewProxy(balancer Balancer) (*Proxy, error)

NewProxy creates a new reverse proxy instance.

func (*Proxy) ServeHTTP

func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles incoming HTTP requests and forwards them to the backend selected by the load balancer.

type RoundRobin

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

func NewRoundRobin

func NewRoundRobin(backends []*Backend) *RoundRobin

func (*RoundRobin) AddBackend

func (r *RoundRobin) AddBackend(b *Backend)

AddBackend implement the Balancer interface

func (*RoundRobin) GetBackends

func (r *RoundRobin) GetBackends() []*Backend

GetBackends implement the Balancer interface

func (*RoundRobin) Next

func (r *RoundRobin) Next(_ *http.Request) (*Backend, error)

func (*RoundRobin) RemoveBackend

func (r *RoundRobin) RemoveBackend(b *Backend)

RemoveBackend implement the Balancer interface

type Route

type Route struct {
	PrefixPath string
	Backends   []*Backend
	Balancer   Balancer
	Proxy      *Proxy
	// contains filtered or unexported fields
}

Route holds all components for a specific routing rule.

type RouteManager

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

RouteManager manages all routing rules.

func NewRouteManager

func NewRouteManager() *RouteManager

NewRouteManager creates a new manager.

func (*RouteManager) AddRoute

func (m *RouteManager) AddRoute(prefixPath string, balancer Balancer) (*Route, error)

AddRoute adds a new routing rule and configures its proxy to strip the given prefix.

func (*RouteManager) GetRoute

func (m *RouteManager) GetRoute(prefixPath string) (*Route, bool)

GetRoute safely retrieves a route.

func (*RouteManager) HandleAddBackends

func (m *RouteManager) HandleAddBackends(w http.ResponseWriter, r *http.Request)

HandleAddBackends handles the HTTP request to add new backends to a route.

func (*RouteManager) HandleGetBackend

func (m *RouteManager) HandleGetBackend(w http.ResponseWriter, r *http.Request)

HandleGetBackend handles the HTTP request to get a backend in a route.

func (*RouteManager) HandleListBackends

func (m *RouteManager) HandleListBackends(w http.ResponseWriter, r *http.Request)

HandleListBackends handles the HTTP request to list backends in a route.

func (*RouteManager) HandleRemoveBackends

func (m *RouteManager) HandleRemoveBackends(w http.ResponseWriter, r *http.Request)

HandleRemoveBackends handles the HTTP request to remove backends from a route.

Jump to

Keyboard shortcuts

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