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  }