Documentation ¶
Overview ¶
Go fd pool implementation, providing client side load balancing.
Basic usage is to set it up with NewGoPool, add a node using AddSingle and then use pool.NewConn() to connect.
After you're done using the connection you either use conn.Put() to put it back into the pool of open connections, or conn.Close() to close it.
If you encounter an error and wish to connect to the next node in the pool you call conn.Next() with either sbalance.Fail or sbalannce.TempFail and then keep using the connection as normal, restarting the communication.
Normally pools are setup with multiple nodes from config or SD. For static configuration you can use the ServiceConfig struct or bconf.
Bconf Configuration ¶
The configuration given to AddBconf or stored in Service Discvory have the following keys. Typically either bconf or json is used to encode. The bconf syntax is shown here, while json would have recursive dictionaries. Almost everything is optional, with defaults as mentioned. A host name and port is required for a node to exist.
host.X.name=ip
host.X.port=port
Specifies the location of the daemon(s) to connect to. X is often a number but does not have to be. In SD it's often a UUID.
host.X.keepalive_port=port
Alternative port used by some API users when the keepalive protocol differs from the normal one. Additional ports can be added by any key ending on port.
host.X.cost=number
How expensive it is to connect to this host relatively the other ones. Used to weigh the random connection sequence. Defaults to 1.
strat=random
strat=hash
strat=seq
Changes the order of the connection attempts from sequential to either random or deterministically random based on a value given by the API user (typically the client ip). By default a random strat is used.
Old keys for these are .random_pick=1 resp. .client_hash=1
failcost=number
If a connection attempt fails, the cost of the host is temporarily changed to this number until a successful query is made. Use 0 for no value, defaults to 100.
tempfailcost=number
If the API user indicates a temporary failure (eg. info:goaway), the cost of the host is changed to this number until a successful query is made. Use 0 for no value, which is also default.
connect_timeout=number
Timeout in milliseconds for the connection attempt. Defaults to 5000 (5 seconds). Note that this is per connection attempt. If a connection fails, the next host is tried, and the connection timeout resets.
retries=number
How many times to iterate the whole host array before giving up.
Index ¶
- Constants
- Variables
- func Dialer(p FdPool) func(ctx context.Context, nw, addr string) (net.Conn, error)
- func DialerFor(p FdPool, service, portKey, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
- func DialerPutOnClose(p FdPool) func(ctx context.Context, nw, addr string) (net.Conn, error)
- func DialerRA(p FdPool, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
- func DialerRAPutOnClose(p FdPool, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
- func GetUrl(p FdPool, scheme, service, portKey string) string
- func PortDialer(p FdPool, portKey, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
- type ErrNoServiceNodes
- type FdPool
- type FdPoolConfig
- type GoPool
- func (p *GoPool) AddBconf(ctx context.Context, conf bconf.Bconf) (string, error)
- func (p *GoPool) AddBconfNetwork(ctx context.Context, conf bconf.Bconf, ipnetw, unixnetw string) (string, error)
- func (p *GoPool) AddConf(ctx context.Context, conf bconf.Bconf) (string, error)
- func (p *GoPool) AddConfNetwork(ctx context.Context, conf bconf.Bconf, ipnetw, unixnetw string) (string, error)
- func (p *GoPool) AddConfig(ctx context.Context, config *ServiceConfig) (string, error)
- func (p *GoPool) AddSingle(ctx context.Context, service, netw, addr string, retries int, ...) error
- func (pool *GoPool) Close() error
- func (pool *GoPool) DialDomain() string
- func (p *GoPool) GetNodePorts(service string) []PortInfo
- func (pool *GoPool) NewConn(ctx context.Context, service, portKey, remoteAddr string) (NetConn, error)
- func (pool *GoPool) SetDialDomain(dom string)
- func (p *GoPool) SetDialFunc(srvname string, ...) error
- func (pool *GoPool) UpdateHosts(ctx context.Context, service string, conf bconf.Bconf) (int, error)
- func (pool *GoPool) UpdateHostsBconf(ctx context.Context, service string, conf bconf.Bconf) (int, error)
- func (pool *GoPool) UpdateHostsConfig(ctx context.Context, service string, hosts map[string]*HostConfig) (int, error)
- type HostConfig
- type HttpConn
- type Logger
- type NetConn
- type PortInfo
- type ServiceConfig
Constants ¶
const ( DefaultCost = 1 DefaultFailCost = 100 DefaultSoftFailCost = 100 DefaultRetries = 1 DefaultConnectTimeout = 1 * time.Second DefaultStrat = sbalance.StratRandom InitialWaitDuration = 1 * time.Second )
Variables ¶
var ( EmptyConfig = errors.New("empty config node") NoSuchService = errors.New("no such service") ConnClosed = errors.New("Use of closed or put connection") )
var PortMap = map[string]string{
"80": "http_port",
"443": "http_port",
"8080": "port",
"8081": "controller_port",
"8082": "keepalive_port,port",
"8180": "plog_port",
}
Port map to support numeric ports mapping to port keys. Mostly to support the net/url package which requires numeric ports. You can modify this if needed, but be careful as it's used without locks.
Functions ¶
func Dialer ¶
Simple dial. the nw parameter is currently ignored, the type of connection is determined by the fd pool service.
You can plug this into for example http.Transport like so:
transport.DialContext = fd_pool.Dialer(p)
Note that when using the dialer, the port given in e.g. a URL might have to be chosen carefully. If possible, you should use a textual port key, e.g. "port", but URLs do not strictly allow anything else than numbers in the port specification. Thus we've added a default mapping from numbers to port keys. "80" and "443" will map to "http_port", while "8080" maps to "port". For more mappings see fd_pool.c symbol default_upmap.
If SetDialDomain has been called, then a hostname to service name conversion is done as it specifies.
func DialerFor ¶
func DialerFor(p FdPool, service, portKey, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
Returns a dialer that ignores the argument given to it and always connects to the service specified to this function.
func DialerPutOnClose ¶
Simple dialer, but when the conn.Close is called, the connection will be put back into the pool instead of closed.
func DialerRA ¶
func DialerRA(p FdPool, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
Dialer that lets you set the remoteAddr parameter given to NewConn.
func DialerRAPutOnClose ¶
func DialerRAPutOnClose(p FdPool, remoteAddr string) func(ctx context.Context, nw, addr string) (net.Conn, error)
Returns a function that can is compatible with net.Dial, put on close version.
Types ¶
type ErrNoServiceNodes ¶
type ErrNoServiceNodes struct {
Service, PortKey string
}
Error returned when no more nodes could be found when calling Next or NewConn.
func (*ErrNoServiceNodes) Error ¶
func (e *ErrNoServiceNodes) Error() string
func (*ErrNoServiceNodes) KVError ¶ added in v1.3.0
func (e *ErrNoServiceNodes) KVError(m map[string]interface{}, key string)
type FdPool ¶
type FdPool interface { Close() error SetDialDomain(dom string) DialDomain() string AddConf(ctx context.Context, conf bconf.Bconf) (string, error) AddSingle(ctx context.Context, service, netw, addr string, retries int, connectTimeout time.Duration) error NewConn(ctx context.Context, service, portKey, remoteAddr string) (NetConn, error) }
Interface covering both GoPool and CPool. AddConf is deprected and will be removed in 2.0
type FdPoolConfig ¶ added in v1.2.0
type FdPoolConfig interface { FdPool AddConfig(ctx context.Context, config *ServiceConfig) (string, error) }
Interface similar to FdPool but containing the new AddConfig function. In 2.0 this will be merged into FdPool.
type GoPool ¶
type GoPool struct {
// contains filtered or unexported fields
}
The main fd pool struct. Typically long-lived, a single pool is created for an application and used throughout. Services are added as needed.
func NewGoPool ¶
Create a new Go fd pool. Should be preferred over NewCPool if you don't need to interact with C code.
func (*GoPool) AddBconf ¶ added in v1.2.0
Add bconf config based nodes to the pool. Uses default stream socket types.
func (*GoPool) AddBconfNetwork ¶ added in v1.2.0
func (p *GoPool) AddBconfNetwork(ctx context.Context, conf bconf.Bconf, ipnetw, unixnetw string) (string, error)
Like AddBconf but allows to specify the network parameter later given to Dial. ipnetw is used for ports and unixnetw is used for paths. Creates a Config and calls AddConfig.
func (*GoPool) AddConf ¶
Add bconf config based nodes to the pool. Uses default stream socket types. Deprecated due to confusing name. AddBconf is the same function.
func (*GoPool) AddConfNetwork ¶
func (p *GoPool) AddConfNetwork(ctx context.Context, conf bconf.Bconf, ipnetw, unixnetw string) (string, error)
Like AddConf but allows to specify the network parameter later given to Dial. ipnetw is used for ports and unixnetw is used for paths. Deprecated due to confusing name. AddBconfNetwork is the same function.
func (*GoPool) AddConfig ¶ added in v1.2.0
Add a service based on a configuration struct. The conf values are copied, the struct can be discarded or reused after the call returns.
func (*GoPool) AddSingle ¶
func (p *GoPool) AddSingle(ctx context.Context, service, netw, addr string, retries int, connectTimeout time.Duration) error
Add a single node to the pool. Uses DefaultCost as cost.
func (*GoPool) DialDomain ¶
func (*GoPool) GetNodePorts ¶
Fetch the internal node state of the pool. Used for debugging purposes. Returns a list of node keys and ports with their costs and number of stored connections.
func (*GoPool) NewConn ¶
func (pool *GoPool) NewConn(ctx context.Context, service, portKey, remoteAddr string) (NetConn, error)
Create a new conneciton to the given service and port keys. remoteAddr can be given to use as a hash for that sbalance strat. The returned NetConn is ready for use. An error might be returned instead if a connection can't be established. It will be the error from the last Dial attempt made, or ErrNoServiceNodes if no connection attempt were made. NoSuchService might also be returned, as well as errors from connecting to Service Discovery if such is configured.
func (*GoPool) SetDialDomain ¶
func (*GoPool) SetDialFunc ¶
func (p *GoPool) SetDialFunc(srvname string, df func(ctx context.Context, nw, addr string) (net.Conn, error)) error
Change the dial function for a specific service. By default a net.Dialer with Timeout set to the configured connect timeout is used. Returns NoSuchService if the service has not been configured.
func (*GoPool) UpdateHosts ¶
Update the nodes for a service, using a bconf node. Deprecated, same as UpdateHostsBconf.
func (*GoPool) UpdateHostsBconf ¶ added in v1.2.0
func (pool *GoPool) UpdateHostsBconf(ctx context.Context, service string, conf bconf.Bconf) (int, error)
Update the nodes for a service, using a bconf node. Creates a ServiceConfig and calls UpdateHostsConfig.
func (*GoPool) UpdateHostsConfig ¶ added in v1.2.0
func (pool *GoPool) UpdateHostsConfig(ctx context.Context, service string, hosts map[string]*HostConfig) (int, error)
Update the nodes for a service, e.g. when a new node is detected via Service Discovery. The hosts given replace the old ones for the service. At least one enabled node must be in hosts or the update won't be made, this is to protect from misconfigurations. Returns the number of sb nodes added, i.e. the number of non-disabled IP addresses found. If 0 is returned nothing was changed. Returns NoSuchService if the service given doesn't exist. Might also return errors from DNS lookup and similar.
type HostConfig ¶ added in v1.2.0
type HostConfig struct { // Name is the dns hostname for this node. If ports only contains a // "path" key this can be empty, otherwise it must have a value. Name string // Ports is a map from portkeys to services (port numbers). The key is checked if it has the suffix "port" or "path". Other entries might be ignored. Ports map[string]string // Cost is the default cost when successfully using this node. Minimum 1. Cost int // Disable marks the node as ignored, same as removing it from the slice. Disabled bool }
HostConfig contains a node specific configuration.
type HttpConn ¶
type HttpConn struct { Req *http.Request Fdc NetConn Tls *tls.Conn // One of Fdc or Tls, for convenience. net.Conn }
type Logger ¶
type Logger interface {
Printf(format string, a ...interface{})
}
Logger interface were used to log from this package. It's no longer in use, the slog package is used instead. It will be removed in the 2.0 release.
type NetConn ¶
type NetConn interface { net.Conn Put() Next(ctx context.Context, status sbalance.ConnStatus) error Reset(ctx context.Context) error PutReset(ctx context.Context) error Peer() string PortKey() string }
Extends net.Conn with functions to move to next node, put back the connection into the pool, and some state extraction.
After you're done using a connection you call either Close or Put. If you chose the latter, the connection will be put back into the pool for later reuse.
If the connection fails for some reason, typically either a timeout or the server giving a "too busy" answer, you can call Next to move the connection to another node in the pool, and then use it again, provided no error was returned. The status should be either sbalance.Fail for a seemingly broken server, or sbalance.TempFail for a more temporary problem. It will return ErrNoServiceNodes if the nodes are depleted and no connection attempt was made. If a connection was attempted but failed the error from the dial function will be returned. After Next any deadlines or other connection specific value set will be removed so you will have to set them again.
Reset can be used to start over from the start. In case of random strat a new node will be chosen. It's rarely used. It will call Close first, while PutReset is the same but calls Put. You must not have called Close or Put if you use these. They have the same return values as Next.
Peer and PortKey gives information about the currently connected to node.
func PutOnClose ¶
Returns a NetConn that when closed will call Put on the passed conn. Returns nil on nil input.
type ServiceConfig ¶ added in v1.2.0
type ServiceConfig struct { // Service name, this is used to determine what service to create. // Note that if you call AddConfig again with the same Service name // it will not update but keep the old values. // If empty string a service name will be generated. Service string // Hosts to add to the service Hosts map[string]*HostConfig // Connection timeout. If 0 then DefaultConnectTimeout is used. ConnectTimeout time.Duration // Retries tells sbalance how many times to go through the entire node // list. Retries int // Strat tells sbalance how to select the next node. Defaults to // StratSeq. StratRand would probably be a better default but StratSeq // is the zero value. Strat sbalance.BalanceStrat // FailCost is the cost to temporarily set when encountering a hard // error (sbalance.Fail) FailCost int // SoftFailCost is the cost to temporarily set when encountering a soft // error (sbalance.SoftFail) SoftFailCost int // NetNetwork is the network parameter to pass to Dialer for "port" // suffix ports. Defaults to "tcp". NetNetwork string // UnixNetwork is the network parameter to pass to Dialer for "path" // suffix ports. Defaults to "unix". UnixNetwork string // DialContext is used to create new connections. By default a // net.Dialer with Timeout set to the configured connect timeout is // used. // ConnectTimeout will be ignored if this is set. DialContext func(ctx context.Context, nw, addr string) (net.Conn, error) // Service Discovery configuration, optional. // This member is currently experimental and might change even in a minor release. // The ambition is to replace it with a similar struct/interface as this one. ServiceDiscovery bconf.Bconf }
func BconfConfig ¶ added in v1.2.0
func BconfConfig(conf bconf.Bconf) *ServiceConfig
Converts bconf fd pool configuration to a ServiceConfig struct. The passed conf parameter is stored in the return value in the ServiceDiscovery member.
func (*ServiceConfig) GetConnectTimeout ¶ added in v1.2.0
func (c *ServiceConfig) GetConnectTimeout() time.Duration
GetConnectTimeout returns the set ConnectTimeout or DefaultConnectTimeout if unset.
func (*ServiceConfig) GetFailCost ¶ added in v1.2.0
func (c *ServiceConfig) GetFailCost() int
GetFailCost returns the set FailCost or DefaultFailCost if unset.
func (*ServiceConfig) GetNetNetwork ¶ added in v1.2.0
func (c *ServiceConfig) GetNetNetwork() string
GetNetNetwork returns the set NetNetwork or "tcp" if unset.
func (*ServiceConfig) GetRetries ¶ added in v1.2.0
func (c *ServiceConfig) GetRetries() int
GetRetries returns the set Retries or DefaultRetries if unset.
func (*ServiceConfig) GetSoftFailCost ¶ added in v1.2.0
func (c *ServiceConfig) GetSoftFailCost() int
GetSoftFailCost returns the set SoftFailCost or DefaultSoftFailCost if unset.
func (*ServiceConfig) GetUnixNetwork ¶ added in v1.2.0
func (c *ServiceConfig) GetUnixNetwork() string
GetUnixNetwork returns the set UnixNetwork or "unix" if unset.