The basic use

registered

client, err := zk.NewClient([]string{"localhost:2181"},logger)
iferr ! =nil{
	panic(err)
}

register := zk.NewRegistrar(client,zk.Service{
	Path: "/services/hello",
	Name: "abc",
	Data: []byte("http://127.0.0.1:8080"),
},logger)

register.Register()
Copy the code

found

client, err := zk.NewClient([]string{"localhost:2181"},logger)
iferr ! =nil{
	panic(err)
}

instancer , err := zk.NewInstancer(client,"/services/hello/abc",logger)
iferr ! =nil {
	panic(err)
}
duration := 500 * time.Millisecond
ctx := context.Background()
factory := helloFactory(ctx, "GET"."hello")
endpointer := sd.NewEndpointer(instancer, factory, logger)

endpointers,_ := endpointer.Endpoints()
Copy the code

The underlying principle

The directory structure

. ├ ─ ─ client. Go client ├ ─ ─ client_test. Go ├ ─ ─ doc. Go ├ ─ ─ instancer. Go service instance ├ ─ ─ instancer_test. Go ├ ─ ─ integration_test. Go ├─ LogWrapper. Go ├─ Registrar. Go util_test.goCopy the code

The main files in the directory are client.go instancer.go Registrar

client.go

type Client interface {
	// Get a set of values with the key prefix
	GetEntries(path string) ([]string, < -chan zk.Event, error)
	//watch specifies the prefix key
	CreateParentNodes(path string) error
	// Register service
	Register(s *Service) error
	// Unregister the service
	Deregister(s *Service) error
	// Stop the zk link
	Stop()
}


type client struct {
	*zk.Conn // combine github.com/samuel/go-zookeeper/zk struct Conn
	clientConfig
	active bool
	quit   chan struct{}}func NewClient(servers []string, logger log.Logger, options ... Option) (Client, error)
func (c *client) CreateParentNodes(path string)
Copy the code

It consists of the following five functions

  • NewClient creates the ZK client, client.conn

  • GetEntries client.Get Obtains the value

  • Deregister client.Delete Deletes the key specified in zK

  • CreateParentNodes Ensures that all the parent nodes in the key have been created. When zK creates child nodes, both parent nodes must exist, such as /a/b/ C. If/A/B does not exist, / A /b/ C cannot be created

  • Register

    • The CreateParentNodes function creates all parent nodes. If any parent nodes already exist, skip this function
    • Client. CreateProtectedEphemeralSequential function, and creates a temporary protection order node (ProtectedEphemeralSequential), at the same time will be the value of this node.
    • Protect sequential temporary nodes
      • Example:cc83db041ac654566228b72cbd541bcb5-abc0000000006 indicates GUID in bold, _c_ is the default prefix, and abc0000000006 is the suffix
      • Temporary node that will be deleted when the ZK link session is closed.
      • Sequential nodes, the names of the nodes created are prefixed with GUID. If the node fails to be created, a normal retry mechanism occurs. During the retry process, the parent path is first searched for the node that contains the GUID. If the node is found, it is assumed to be a missing node that was successfully created on the first attempt and returned to the caller.
      • Protects nodes. Self-suffixes key to ensure unique node names

registrar.go

type Registrar struct {
  / / the zk client
	client  Client
	// The registered service
	service Service
	logger  log.Logger
}

// The key and address of the service
type Service struct {
	Path string // Service discovery namespace: /service/hello/
	Name string // Example: ABC
	Data []byte // Service instance data exists, for example, 10.0.2.10:80
	node string / / store ProtectedEphemeralSequential (temporary order) to protect the name of the node, easy to Deregister function cancelled service
}

func NewRegistrar(client Client, service Service, logger log.Logger) *Registrar
func (r *Registrar) Register(a) 
func (r *Registrar) Deregister(a)
Copy the code

Contains the following three functions

  • NewRegistrar create the Registrar
  • Register invokes the Register method in client.go
  • Deregister calls the Deregister method in client.go

instancer.go

type Instancer struct {
  // Instance cache
	cache  *instance.Cache
	/ / the zk client
	client Client
	// Service zK node value
	path   string
	logger log.Logger
	//Instancer exits the channel
	quitc  chan struct{}}func NewInstancer(c Client, path string, logger log.Logger) (*Instancer, error)
func (s *Instancer) loop(eventc <-chan zk.Event)
func (s *Instancer) Stop(a)
func (s *Instancer) Register(ch chan<- sd.Event) 
func (s *Instancer) state(a) sd.Event {
Copy the code

It consists of the following five functions

  • NewInstancer
    • Call the client.go GetEntries function to obtain a set of service addresses
  • loop
    • Listen for the key corresponding to the service
  • Stop
    • Disabling Service Listening
  • Register
  • Deregister