package etcd import ( "time" "context" "fmt" clientv3 "go.etcd.io/etcd/client/v3" ) //创建租约注册服务 type ServiceReg struct { client *clientv3.Client lease clientv3.Lease leaseResp *clientv3.LeaseGrantResponse canclefunc func() keepAliveChan <-chan *clientv3.LeaseKeepAliveResponse key string } func NewServiceReg(addr []string, timeNum int64) (*ServiceReg, 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 { return nil, err } ser := &ServiceReg{ client: client, } if err := ser.setLease(timeNum); err != nil { return nil, err } go ser.ListenLeaseRespChan() return ser, nil } //设置租约 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) _, 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 Etcdrun() { ser,_ := NewServiceReg([]string{"101.201.121.115:2379"},5) ser.PutService("/Server/001","LeitServer") //select{} }