discovery

package
v4.19.0 Latest Latest
Warning

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

Go to latest
Published: Apr 24, 2024 License: Apache-2.0 Imports: 25 Imported by: 0

README

GRPCSrvBuilder

This build returns a GRPC resolver which will preform an DNS SRV record lookup on the provided domain name. Combined with round-robin load balancing, it will instruct the GRPC client to load balance each request to every node returned by the DNS SRV lookup.


package main

import (
	"context"
	"time"

	"github.com/davecgh/go-spew/spew"
	"github.com/mailgun/holster/v4/discovery"
	"github.com/mailgun/ratelimits/v2"
	"github.com/sirupsen/logrus"
	"google.golang.org/grpc"
	"google.golang.org/grpc/resolver"
)

func main() {
	// Optional, will log the list of addresses dns-srv discovered when requesting the SRV records
	discovery.GRPCSrvLogAddresses = false

	// Optional, allows you to override the default logger. dns-srv will log an error when it is 
	// unable to request the SRV records.
	discovery.GRPCSrvDefaultLogger = logrus.New()
	
	// Required to register `dns-srv:///` as a schema GRPC can understand
	resolver.Register(discovery.NewGRPCSRVBuilder())

	c, err := grpc.Dial("dns-srv:///ratelimits-grpc.service.us-east4.prod.mailforce:8201",
		// Enable round-robin load balancing
		grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin":{}}]}`),
		grpc.WithInsecure(),
	)
	if err != nil {
		panic(err)
	}

	rl := ratelimits.NewV1Client(c)

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
	defer cancel()

	resp, err := rl.HealthCheck(ctx, &ratelimits.HealthCheckReq{})
	if err != nil {
		panic(err)
	}
	spew.Dump(resp)

	// It can take some time for dns-srv to fetch all and resolve all the SRV
	// records for a service, especially if there are a lot of them.
	time.Sleep(time.Second * 15)

	// These requests should round-robin
	resp, err = rl.HealthCheck(ctx, &ratelimits.HealthCheckReq{})
	if err != nil {
		panic(err)
	}
	spew.Dump(resp)
	resp, _ = rl.HealthCheck(ctx, &ratelimits.HealthCheckReq{})
	spew.Dump(resp)
	resp, _ = rl.HealthCheck(ctx, &ratelimits.HealthCheckReq{})
	spew.Dump(resp)
	resp, _ = rl.HealthCheck(ctx, &ratelimits.HealthCheckReq{})
	spew.Dump(resp)
	
	c.Close()
}

SRV Resolver

discovery.GetSRVAddresses() can be used directly as a utility for querying SRV DNS records. For example:

// Using "" as the dnsServer argument uses the Golang built-in resolver
addresses, err = discovery.GetSRVAddresses("mytest.service.consul", "")

If valid, will return a list of IP:Port records associated to the given DNS entry.

Note: you can specify an explicit DNS server instead. Using "" uses the DNS resolver of the machine.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrMissingAddr         = errors.New("missing address")
	ErrEndsWithColon       = errors.New("missing port after port-separator colon")
	ErrIPAddressNotAllowed = errors.New("ip address is not allowed; must be a dns service name")
	GRPCSrvDefaultPort     = "443"
	GRPCSrvDefaultLogger   logrus.FieldLogger

	// GRPCSrvLogAddresses if true then GRPC will log the list of addresses received when making an SRV
	GRPCSrvLogAddresses = false
)

Functions

func GetSRVAddresses

func GetSRVAddresses(dnsName, dnsServer string) ([]string, error)

Given a DNS name return a list of addresses returned by the getting the SRV records from DNS for that name.

func NewGRPCSRVBuilder added in v4.9.0

func NewGRPCSRVBuilder() resolver.Builder

NewGRPCSRVBuilder creates a srvResolverBuilder which is used to factory SRV-DNS resolvers.

func NewLogWriter

func NewLogWriter(log logrus.FieldLogger) *io.PipeWriter

Types

type Consul

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

func (*Consul) Close

func (cs *Consul) Close(ctx context.Context) error

func (*Consul) GetPeers

func (cs *Consul) GetPeers(ctx context.Context) ([]Peer, error)

type ConsulConfig

type ConsulConfig struct {
	// This is the consul client config; typically created by calling api.DefaultConfig()
	ClientConfig *api.Config

	// The name of the catalog we should register under; should be common to all peers in the catalog
	CatalogName string

	// Information about this peer which should be shared with all other peers in the catalog
	Peer Peer

	// This is an address the will be registered with consul so it can preform liveliness checks
	LivelinessAddress string

	// A callback function which is called when the member list changes
	OnUpdate OnUpdateFunc

	// An interface through which logging will occur; usually *logrus.Entry
	Logger logrus.FieldLogger
}

type MemberList

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

func (*MemberList) Close

func (m *MemberList) Close(ctx context.Context) error

func (*MemberList) GetPeers

func (m *MemberList) GetPeers(_ context.Context) ([]Peer, error)

type MemberListConfig

type MemberListConfig struct {
	// This is the address:port the member list protocol listen for other peers on.
	BindAddress string
	// This is the address:port the member list protocol will advertise to other peers. (Defaults to BindAddress)
	AdvertiseAddress string
	// Metadata about this peer which should be shared with other peers
	Peer Peer
	// A list of peers this member list instance can contact to find other peers.
	KnownPeers []string
	// A callback function which is called when the member list changes.
	OnUpdate OnUpdateFunc
	// If not nil, use this config instead of ml.DefaultLANConfig()
	MemberListConfig *ml.Config
	// An interface through which logging will occur; usually *logrus.Entry
	Logger logrus.FieldLogger
}

type Members

type Members interface {
	// Returns the peers currently registered
	GetPeers(context.Context) ([]Peer, error)
	// Removes our peer from the member list and closes all connections
	Close(context.Context) error
}

func NewConsul

func NewConsul(conf *ConsulConfig) (Members, error)

func NewMemberList

func NewMemberList(ctx context.Context, conf MemberListConfig) (Members, error)

type OnUpdateFunc

type OnUpdateFunc func([]Peer)

type Peer

type Peer struct {
	// An ID the uniquely identifies this peer
	ID string
	// The metadata associated with this peer
	Metadata []byte
	// Is true if this Peer refers to our instance
	IsSelf bool
}

Jump to

Keyboard shortcuts

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