package xjutils import ( "context" "encoding/json" "fmt" "github.com/coreos/etcd/clientv3" "log" "os" "time" ) //创建租约注册服务 type ServiceReg struct { client *clientv3.Client lease clientv3.Lease leaseResp *clientv3.LeaseGrantResponse canclefunc func() keepAliveChan <-chan *clientv3.LeaseKeepAliveResponse key string } type Val struct{ StartTime string UpdateTime string Status int //状态:1正常 2下线 Weight int //权重:默认为1 Metatata string //元数据 Health int //健康状态:1健康 2不健康 3更不健康 ,数值越大越不健康 } func NewServiceReg(addr []string, timeNum int64) *ServiceReg { log.Println("开始连接etcd...") var err error conf := clientv3.Config{ Endpoints: addr, DialTimeout: 5 * time.Second, } var ( client *clientv3.Client ) if clientTem, err := clientv3.New(conf); err == nil { client = clientTem } else { log.Println("连接etcd出错了") log.Println(err) os.Exit(1) } ser := &ServiceReg{ client: client, } if err := ser.setLease(timeNum); err != nil { log.Println("连接etcd出错了") log.Println(err) os.Exit(1) } go ser.ListenLeaseRespChan() if err != nil { log.Println("连接etcd出错了") log.Println(err) os.Exit(1) } log.Println("连接etcd...OK") return ser } //设置租约 func (this *ServiceReg) setLease(timeNum int64) error { lease := clientv3.NewLease(this.client) //设置租约时间 leaseResp, err := lease.Grant(context.TODO(), timeNum) if err != nil { return err } //设置续租 ctx, cancelFunc := context.WithCancel(context.TODO()) leaseRespChan, err := lease.KeepAlive(ctx, leaseResp.ID) if err != nil { return err } this.lease = lease this.leaseResp = leaseResp this.canclefunc = cancelFunc this.keepAliveChan = leaseRespChan return nil } //监听 续租情况 func (this *ServiceReg) ListenLeaseRespChan() { for { select { case leaseKeepResp := <-this.keepAliveChan: if leaseKeepResp == nil { fmt.Printf("已经关闭续租功能\n") return } else { //fmt.Printf("续租成功\n") } } } } //通过租约 注册服务 func (this *ServiceReg) PutService(key, val string) error { kv := clientv3.NewKV(this.client) key = "services/" + key if val == "" { value := Val{ StartTime: time.Now().Format("2006-01-02 15:04:05"), UpdateTime: time.Now().Format("2006-01-02 15:04:05"), Status: 1, Weight: 1, Metatata: "", Health: 1, } data,_ := json.Marshal(&value) val = string(data) } _, err := kv.Put(context.TODO(), key, val, clientv3.WithLease(this.leaseResp.ID)) return err } //撤销租约 func (this *ServiceReg) RevokeLease() error { this.canclefunc() time.Sleep(2 * time.Second) _, err := this.lease.Revoke(context.TODO(), this.leaseResp.ID) return err } //func main() { // //ser,_ := NewServiceReg([]string{"192.168.147.151:2379"},5) // ser,_ := NewServiceReg([]string{"127.0.0.1:2379"},5) // ser.PutService("config","192.168.1.101:8001") // ser.PutService("config","192.168.1.102:8001") // select{} //}