github.com/polarismesh/polaris@v1.17.8/bootstrap/self_checker.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package bootstrap 19 20 import ( 21 "context" 22 "sync" 23 "time" 24 25 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 26 27 api "github.com/polarismesh/polaris/common/api/v1" 28 "github.com/polarismesh/polaris/common/log" 29 "github.com/polarismesh/polaris/service" 30 "github.com/polarismesh/polaris/service/healthcheck" 31 ) 32 33 type SelfHeathChecker struct { 34 instances []*apiservice.Instance 35 interval int 36 cancel context.CancelFunc 37 wg *sync.WaitGroup 38 discoverSvr service.DiscoverServer 39 hcServer *healthcheck.Server 40 } 41 42 func NewSelfHeathChecker(instances []*apiservice.Instance, interval int) (*SelfHeathChecker, error) { 43 hcServer, err := healthcheck.GetServer() 44 if nil != err { 45 return nil, err 46 } 47 discoverSvr, err := service.GetOriginServer() 48 if nil != err { 49 return nil, err 50 } 51 for _, instance := range instances { 52 log.Infof("scheduled check for instance %s:%d", 53 instance.GetHost().GetValue(), instance.GetPort().GetValue()) 54 } 55 return &SelfHeathChecker{ 56 instances: instances, 57 interval: interval, 58 discoverSvr: discoverSvr, 59 hcServer: hcServer, 60 }, nil 61 } 62 63 func (s *SelfHeathChecker) Start() { 64 s.wg = &sync.WaitGroup{} 65 s.wg.Add(1) 66 var ctx context.Context 67 ctx, s.cancel = context.WithCancel(context.Background()) 68 ticker := time.NewTicker(time.Duration(s.interval) * time.Second) 69 for { 70 select { 71 case <-ctx.Done(): 72 log.Info("[Bootstrap] server health check has been terminated") 73 s.wg.Done() 74 ticker.Stop() 75 return 76 case <-ticker.C: 77 for _, instance := range s.instances { 78 rsp := s.hcServer.Report(context.Background(), instance) 79 80 switch rsp.GetCode().GetValue() { 81 case api.ExecuteSuccess: 82 continue 83 case api.NotFoundResource: 84 // 这里可能实例被错误摘除了,这里重新触发一次重注册流程,确保核心流程不受影响 85 log.Infof("[Bootstrap] heartbeat not founf instance for %s:%d, code is %d, try re-register", 86 instance.GetHost().GetValue(), instance.GetPort().GetValue(), rsp.GetCode().GetValue()) 87 resp := s.discoverSvr.CreateInstances(genContext(), []*apiservice.Instance{instance}) 88 if resp.GetCode().GetValue() != api.ExecuteSuccess { 89 log.Errorf("[Bootstrap] re-register fail for %s:%d, code is %d, info %s", 90 instance.GetHost().GetValue(), instance.GetPort().GetValue(), 91 resp.GetCode().GetValue(), resp.GetInfo().GetValue()) 92 } 93 default: 94 log.Errorf("[Bootstrap] heartbeat fail for %s:%d, code is %d, info %s", 95 instance.GetHost().GetValue(), instance.GetPort().GetValue(), 96 rsp.GetCode().GetValue(), rsp.GetInfo().GetValue()) 97 } 98 } 99 } 100 } 101 } 102 103 func (s *SelfHeathChecker) Stop() { 104 s.cancel() 105 s.wg.Wait() 106 }