balancer

package module
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2022 License: MIT Imports: 11 Imported by: 0

README

balancer

Build status codecov Go Report Go Reference ⚠ API is not stable yet.

A simple client-side HTTP load balancer for go applications.

http.Client does not balance requests across multiple backend servers (a.k.a. DNS round-robin) unless persistent connections are disabled. balancer was created to provide DNS-based request-level HTTP load balancing for go clients.

This library originated as a fork of github.com/esiqveland/balancer but has since been fully rewritten and it contains no upstream code.

This library also contains a number of net.Resolver middlewares that add useful features such as caching, timeout, and request deduplication (for thundering herd protection).

Scope

balancer does not do health checking and does not monitor status of any hosts. This is left up to external mechanisms, and assumes hosts returned by the DNS resolver are healthy.

balancer does not retry or otherwise try to fix problems, leaving this up to the caller.

As the net and net/http packages do not expose the required functionality, balancer disables the dual stack (IPv4/IPv6) support that is normally automatically provided by those packages. Care must be taken to specify the correct stack to use. See Wrap for details.

Documentation

Overview

Example
package main

import (
	"net"
	"net/http"

	"github.com/CAFxX/balancer"
)

func main() {
	client := *http.DefaultClient
	client.Transport = balancer.Wrap(http.DefaultTransport, net.DefaultResolver, "ip4")
	// Requests using the client will now be balanced across all IPv4 addressed of the hostname.
	client.Get("http://example.com")
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Wrap

func Wrap(rt http.RoundTripper, resolver Resolver, af string) http.RoundTripper

Wrap returns an http.RoundTripper wrapping the provided http.RoundTripper that adds DNS-based load balancing (using the provided Resolver) to requests sent by the HTTP client.

The resolver is used to resolve the IP addresses of the hostname in each request. The roundtripper does not cache DNS responses, so the resolver is invoked for each request (you can use the CachingResolver to add caching to any Resolver). net.Resolver and net.DefaultResolver implement the Resolver interface.

The af parameter must be one of "ip4", "ip6", or "ip", and is passed as-is to Resolver.LookupNetIP to specify which IP family addresses to use (IPv4, IPv6, or both). If your service does not support IPv6 you should set this to "ip4" (see net.Resolver for details). Normally the net package automatically attempts to use both (see net.Dialer for details), but Wrap modified the request by replacing the hostname of the server with one of its IPs (chosen at random, if the hostname resolves to multiple IPs), so by the time the request reaches the net.Dialer it targets a specific server IP, instead of the server hostname. As a result net.Dialer is unable to automatically pick the appropriate IP family. For this reason it is extremely important to specify the correct af (address family) value.

Types

type CachingResolver

type CachingResolver struct {
	Resolver Resolver      // Wrapped DNS resolver.
	TTL      time.Duration // How long to cache positive results for. 0 disables caching for positive results.
	NegTTL   time.Duration // How long to cache negative results for. 0 disables caching for negative results.
	// contains filtered or unexported fields
}

CachingResolver caches responses from the wrapped DNS resolver for the specified amount of time.

CachingResolver does not implement a timeout for DNS queries: for that you can use a TimeoutResolver. Similarly, it does not implement concurrent request deduplication: for that you can use a SingleflightResolver. See ExampleAdvanced for the recommended way of composing these additional resolvers.

func (*CachingResolver) LookupNetIP

func (c *CachingResolver) LookupNetIP(ctx context.Context, af, host string) ([]netip.Addr, error)

type Resolver

type Resolver interface {
	LookupNetIP(ctx context.Context, af, host string) ([]netip.Addr, error)
}

type SingleflightResolver

type SingleflightResolver struct {
	Resolver Resolver // Wrapped DNS resolver.
	// contains filtered or unexported fields
}

SingleflightResolver allows to deduplicate concurrent requests for the DNS records of the same hostname.

If multiple concurrent requests to resolve the same hostname are performed, SingleflightResolver will allow the first to proceed. Additional requests are paused until the parent resolver has responded, at which point the response is provided to all pending requests for that hostname. Note that the request to the parent resolver is cancelled only once all pending requests for that hostname have been cancelled.

func (*SingleflightResolver) LookupNetIP

func (r *SingleflightResolver) LookupNetIP(ctx context.Context, af, host string) ([]netip.Addr, error)

type TimeoutResolver

type TimeoutResolver struct {
	Resolver Resolver      // Wrapped DNS resolver.
	Timeout  time.Duration // How long to wait for a response from the wrapped DNS resolver. 0 disables the timeout.
}

TimeoutResolver allows to specify a timeout for DNS requests.

func (*TimeoutResolver) LookupNetIP

func (t *TimeoutResolver) LookupNetIP(ctx context.Context, af, host string) ([]netip.Addr, error)

Jump to

Keyboard shortcuts

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