You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.3 KiB

package discovery
import (
"context"
"errors"
clientv3 "go.etcd.io/etcd/client/v3"
"math/rand"
"time"
)
type Discovery interface {
// 获取某个服务器的一个实例地址
GetServiceAddr(serviceName string) (string, error)
// 监控某个服务的地址变化
WatchService(serviceName string) error
}
type DiscoveryEtcd struct {
cli *clientv3.Client
}
// 实例化的方法
func NewDiscoveryEtcd(endpoints []string) (*DiscoveryEtcd, error) {
// 一没有etcd的地址直接返回
if len(endpoints) == 0 {
return nil, errors.New("endpoints is empty")
}
// 二连接etcd
cli, err := clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: 3 * time.Second,
})
if err != nil {
return nil, err
}
// 实例化
de := &DiscoveryEtcd{cli: cli}
return de, nil
}
func (de *DiscoveryEtcd) GetServiceAddr(serviceName string) (string, error) {
// 执行 Get 操作
getResp, err := de.cli.Get(context.Background(), serviceName, clientv3.WithPrefix())
if err != nil {
return "", err
}
// 处理查询到的结果
if len(getResp.Kvs) == 0 {
return "", errors.New("service not found")
}
// 采用随机的LBLoadBalance 算法
randIndex := rand.Intn(len(getResp.Kvs)) // [0, n)
addr := string(getResp.Kvs[randIndex].Value)
// 返回地址
return addr, nil
}