🎉 Initial Commit
This commit is contained in:
51
pkg/shared/registrar/README.md
Normal file
51
pkg/shared/registrar/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Registrar
|
||||
|
||||
The Registrar is the service discovery system of the DysonNetwork.
|
||||
Here are a port to the Golang in order to support other Golang services.
|
||||
|
||||
To use the system, try build with these API:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"yourmodule/registry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
endpoints := []string{"localhost:2379"}
|
||||
|
||||
registrar, err := registry.NewServiceRegistrar(endpoints)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating registrar: %v", err)
|
||||
}
|
||||
|
||||
serviceName := "orders"
|
||||
host := "10.0.0.5"
|
||||
port := 5000
|
||||
ttl := int64(30)
|
||||
|
||||
err = registrar.Register(serviceName, host, port, ttl)
|
||||
if err != nil {
|
||||
log.Fatalf("Register error: %v", err)
|
||||
}
|
||||
log.Println("Service registered")
|
||||
|
||||
// Wait for termination
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-stop
|
||||
|
||||
err = registrar.Deregister()
|
||||
if err != nil {
|
||||
log.Printf("Deregister error: %v", err)
|
||||
} else {
|
||||
log.Println("Service deregistered")
|
||||
}
|
||||
}
|
||||
```
|
||||
84
pkg/shared/registrar/mod.go
Normal file
84
pkg/shared/registrar/mod.go
Normal file
@@ -0,0 +1,84 @@
|
||||
// Package registrar is for the service discovery system
|
||||
package registrar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
type ServiceRegistrar struct {
|
||||
client *clientv3.Client
|
||||
leaseID clientv3.LeaseID
|
||||
ttl int64
|
||||
key string
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
// NewServiceRegistrar creates a registrar with the given etcd client
|
||||
func NewServiceRegistrar(endpoints []string) (*ServiceRegistrar, error) {
|
||||
cfg := clientv3.Config{
|
||||
Endpoints: endpoints,
|
||||
DialTimeout: 5 * time.Second,
|
||||
}
|
||||
|
||||
cli, err := clientv3.New(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServiceRegistrar{client: cli}, nil
|
||||
}
|
||||
|
||||
// Register service with etcd using TTL lease
|
||||
func (r *ServiceRegistrar) Register(serviceName string, servicePart string, instanceID string, host string, port int, ttlSeconds int64) error {
|
||||
r.ttl = ttlSeconds
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
r.key = fmt.Sprintf("/services/%s/%s/%s", serviceName, servicePart, instanceID)
|
||||
|
||||
// Create lease
|
||||
leaseResp, err := r.client.Grant(ctx, r.ttl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.leaseID = leaseResp.ID
|
||||
|
||||
// Put key with lease
|
||||
_, err = r.client.Put(ctx, r.key, fmt.Sprintf("%s:%d", host, port), clientv3.WithLease(r.leaseID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Keep alive context
|
||||
kaCtx, kaCancel := context.WithCancel(context.Background())
|
||||
r.cancel = kaCancel
|
||||
|
||||
// Keep lease alive
|
||||
go func() {
|
||||
ch, err := r.client.KeepAlive(kaCtx, r.leaseID)
|
||||
if err != nil {
|
||||
fmt.Printf("KeepAlive error: %v\n", err)
|
||||
return
|
||||
}
|
||||
for range ch {
|
||||
// optionally inspect TTL updates here
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deregister removes the registered key and stops keep-alive
|
||||
func (r *ServiceRegistrar) Deregister() error {
|
||||
if r.cancel != nil {
|
||||
r.cancel()
|
||||
}
|
||||
|
||||
_, err := r.client.Delete(context.Background(), r.key)
|
||||
return err
|
||||
}
|
||||
21
pkg/shared/registrar/retirever.go
Normal file
21
pkg/shared/registrar/retirever.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package registrar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
func (r *ServiceRegistrar) ListInstance(serviceName string, servicePart string) ([]string, error) {
|
||||
keyPrefix := fmt.Sprintf("/services/%s/%s", serviceName, servicePart)
|
||||
resp, err := r.client.Get(context.Background(), keyPrefix, clientv3.WithPrefix())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var result []string
|
||||
for _, kv := range resp.Kvs {
|
||||
result = append(result, string(kv.Value))
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user