-
Notifications
You must be signed in to change notification settings - Fork 0
/
discovery.go
67 lines (60 loc) · 1.46 KB
/
discovery.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package discovery
import (
"context"
"fmt"
"time"
"github.com/rshulabs/HgCache/internal/pkg/discovery/lb"
"github.com/rshulabs/HgCache/pkg/logx"
clientv3 "go.etcd.io/etcd/client/v3"
)
type Discovery interface {
// 获取服务器的一个地址
GetServiceAddr(serviceName string) (string, error)
// 监控服务地址变化
WatchService(serviceName string) error
}
type EtcdDiscovery struct {
cli *clientv3.Client
}
func NewEtcdDiscovery(endpoints []string) (*EtcdDiscovery, error) {
// 校验
if len(endpoints) == 0 {
return nil, fmt.Errorf("endpoints cannot be empty")
}
cli, err := clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: 3 * time.Second,
})
if err != nil {
return nil, err
}
return &EtcdDiscovery{
cli: cli,
}, nil
}
func (d *EtcdDiscovery) GetServiceAddr(serviceName, key string) (string, error) {
// get --prefix
gResp, err := d.cli.Get(context.Background(), serviceName, clientv3.WithPrefix())
if err != nil {
return "", err
}
if len(gResp.Kvs) == 0 {
return "", fmt.Errorf("%s service is not found", serviceName)
}
var nodes []string
for _, v := range gResp.Kvs {
nodes = append(nodes, string(v.Value))
}
cHash := lb.NewMap(100, nil)
cHash.Add(nodes...)
addr := cHash.Get(key)
return addr, nil
}
func (d *EtcdDiscovery) WatchService(serviceName string) error {
ch := d.cli.Watch(context.Background(), serviceName, clientv3.WithPrefix())
select {
case <-ch:
logx.Info("service changed")
}
return nil
}