github.com/polarismesh/polaris@v1.17.8/plugin/healthchecker/memory/checker_memory.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 heartbeatmemory 19 20 import ( 21 "context" 22 "sync/atomic" 23 24 commonLog "github.com/polarismesh/polaris/common/log" 25 commontime "github.com/polarismesh/polaris/common/time" 26 "github.com/polarismesh/polaris/common/utils" 27 "github.com/polarismesh/polaris/plugin" 28 ) 29 30 // 把操作记录记录到日志文件中 31 const ( 32 // PluginName plugin name 33 PluginName = "heartbeatMemory" 34 ) 35 36 var log = commonLog.GetScopeOrDefaultByName(commonLog.HealthcheckLoggerName) 37 38 // HeartbeatRecord record for heartbeat 39 type HeartbeatRecord struct { 40 Server string 41 CurTimeSec int64 42 Count int64 43 } 44 45 // MemoryHealthChecker memory health checker 46 type MemoryHealthChecker struct { 47 hbRecords *utils.SyncMap[string, *HeartbeatRecord] 48 suspendTimeSec int64 49 } 50 51 // Name return plugin name 52 func (r *MemoryHealthChecker) Name() string { 53 return PluginName 54 } 55 56 // Initialize initialize plugin 57 func (r *MemoryHealthChecker) Initialize(c *plugin.ConfigEntry) error { 58 r.hbRecords = utils.NewSyncMap[string, *HeartbeatRecord]() 59 return nil 60 } 61 62 // Destroy plugin destruction 63 func (r *MemoryHealthChecker) Destroy() error { 64 return nil 65 } 66 67 // Type for health check plugin, only one same type plugin is allowed 68 func (r *MemoryHealthChecker) Type() plugin.HealthCheckType { 69 return plugin.HealthCheckerHeartbeat 70 } 71 72 // Report process heartbeat info report 73 func (r *MemoryHealthChecker) Report(ctx context.Context, request *plugin.ReportRequest) error { 74 record := &HeartbeatRecord{ 75 Server: request.LocalHost, 76 CurTimeSec: request.CurTimeSec, 77 Count: request.Count, 78 } 79 r.hbRecords.Store(request.InstanceId, record) 80 log.Debugf("[HealthCheck][MemoryCheck]add hb record, instanceId %s, record %+v", request.InstanceId, record) 81 return nil 82 } 83 84 // Query queries the heartbeat time 85 func (r *MemoryHealthChecker) Query(ctx context.Context, request *plugin.QueryRequest) (*plugin.QueryResponse, error) { 86 record, ok := r.hbRecords.Load(request.InstanceId) 87 if !ok { 88 return &plugin.QueryResponse{ 89 LastHeartbeatSec: 0, 90 }, nil 91 } 92 log.Debugf("[HealthCheck][MemoryCheck]query hb record, instanceId %s, record %+v", request.InstanceId, record) 93 return &plugin.QueryResponse{ 94 Server: record.Server, 95 LastHeartbeatSec: record.CurTimeSec, 96 Count: record.Count, 97 }, nil 98 } 99 100 func (r *MemoryHealthChecker) skipCheck(instanceId string, expireDurationSec int64) bool { 101 suspendTimeSec := r.SuspendTimeSec() 102 localCurTimeSec := commontime.CurrentMillisecond() / 1000 103 if suspendTimeSec > 0 && localCurTimeSec >= suspendTimeSec && localCurTimeSec-suspendTimeSec < expireDurationSec { 104 log.Infof("[Health Check][MemoryCheck]health check redis suspended, "+ 105 "suspendTimeSec is %d, localCurTimeSec is %d, expireDurationSec is %d, instanceId %s", 106 suspendTimeSec, localCurTimeSec, expireDurationSec, instanceId) 107 return true 108 } 109 return false 110 } 111 112 // Check Report process the instance check 113 func (r *MemoryHealthChecker) Check(request *plugin.CheckRequest) (*plugin.CheckResponse, error) { 114 queryResp, err := r.Query(context.Background(), &request.QueryRequest) 115 if err != nil { 116 return nil, err 117 } 118 lastHeartbeatTime := queryResp.LastHeartbeatSec 119 checkResp := &plugin.CheckResponse{ 120 LastHeartbeatTimeSec: lastHeartbeatTime, 121 } 122 curTimeSec := request.CurTimeSec() 123 log.Debugf("[HealthCheck][MemoryCheck]check hb record, cur is %d, last is %d", curTimeSec, lastHeartbeatTime) 124 if r.skipCheck(request.InstanceId, int64(request.ExpireDurationSec)) { 125 checkResp.StayUnchanged = true 126 return checkResp, nil 127 } 128 if curTimeSec > lastHeartbeatTime { 129 if curTimeSec-lastHeartbeatTime >= int64(request.ExpireDurationSec) { 130 // 心跳超时 131 checkResp.Healthy = false 132 133 if request.Healthy { 134 log.Infof("[Health Check][MemoryCheck]health check expired, "+ 135 "last hb timestamp is %d, curTimeSec is %d, expireDurationSec is %d, instanceId %s", 136 lastHeartbeatTime, curTimeSec, request.ExpireDurationSec, request.InstanceId) 137 } else { 138 checkResp.StayUnchanged = true 139 } 140 return checkResp, nil 141 } 142 } 143 checkResp.Healthy = true 144 if !request.Healthy { 145 log.Infof("[Health Check][MemoryCheck]health check resumed, "+ 146 "last hb timestamp is %d, curTimeSec is %d, expireDurationSec is %d instanceId %s", 147 lastHeartbeatTime, curTimeSec, request.ExpireDurationSec, request.InstanceId) 148 } else { 149 checkResp.StayUnchanged = true 150 } 151 152 return checkResp, nil 153 } 154 155 // Delete delete the id 156 func (r *MemoryHealthChecker) Delete(ctx context.Context, id string) error { 157 r.hbRecords.Delete(id) 158 return nil 159 } 160 161 func (r *MemoryHealthChecker) Suspend() { 162 curTimeMilli := commontime.CurrentMillisecond() / 1000 163 log.Infof("[Health Check][MemoryCheck] suspend checker, start time %d", curTimeMilli) 164 atomic.StoreInt64(&r.suspendTimeSec, curTimeMilli) 165 } 166 167 // SuspendTimeSec get suspend time in seconds 168 func (r *MemoryHealthChecker) SuspendTimeSec() int64 { 169 return atomic.LoadInt64(&r.suspendTimeSec) 170 } 171 172 func (r *MemoryHealthChecker) DebugHandlers() []plugin.DebugHandler { 173 return []plugin.DebugHandler{} 174 } 175 176 func init() { 177 d := &MemoryHealthChecker{} 178 plugin.RegisterPlugin(d.Name(), d) 179 }