// // 去ZK注册当前的Service // func RegisterService(serviceName, frontendAddr, serviceId string, topo *Topology, evtExit chan interface{}, workDir string, codeUrlVerion string, state *atomic2.Bool, stateChan chan bool) *ServiceEndpoint { // 1. 准备数据 // 记录Service Endpoint的信息 servicePath := topo.ProductServicePath(serviceName) // 确保东西存在 if ok, _ := topo.Exist(servicePath); !ok { topo.CreateDir(servicePath) } // 用来从zookeeper获取事件 evtbus := make(chan interface{}) // 2. 将信息添加到Zk中, 并且监控Zk的状态(如果添加失败会怎么样?) endpoint := NewServiceEndpoint(serviceName, serviceId, frontendAddr, workDir, codeUrlVerion) // deployPath // 为了保证Add是干净的,需要先删除,保证自己才是Owner endpoint.DeleteServiceEndpoint(topo) // 如果没有状态,或状态为true, 则上线 if state == nil || state.Get() { endpoint.AddServiceEndpoint(topo) } go func() { for true { // Watch的目的是监控: 当前的zk session的状态, 如果session出现异常,则重新注册 _, err := topo.WatchNode(servicePath, evtbus) if err == nil { // 如果成功添加Watch, 则等待退出,或者ZK Event select { case <-evtExit: return case <-stateChan: // 如何状态变化(则重新注册) endpoint.DeleteServiceEndpoint(topo) if state == nil || state.Get() { endpoint.AddServiceEndpoint(topo) } case e := <-evtbus: event := e.(topozk.Event) if event.State == topozk.StateExpired || event.Type == topozk.EventNotWatching { // Session过期了,则需要删除之前的数据, // 因为当前的session不是之前的数据的Owner endpoint.DeleteServiceEndpoint(topo) if state == nil || state.Get() { endpoint.AddServiceEndpoint(topo) } } } } else { // 如果添加Watch失败,则等待退出,或等待timer接触,进行下一次尝试 timer := time.NewTimer(time.Second * time.Duration(10)) log.ErrorErrorf(err, "Reg Failed, Wait 10 seconds...., %v", err) select { case <-evtExit: return case <-timer.C: // pass } } } }() return endpoint }