1 Star 0 Fork 0

h79/goutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
health.go 2.64 KB
一键复制 编辑 原始数据 按行查看 历史
package health
import (
"gitee.com/h79/goutils/common/debug"
commonhttp "gitee.com/h79/goutils/common/http"
"gitee.com/h79/goutils/common/logger"
"gitee.com/h79/goutils/common/result"
"gitee.com/h79/goutils/common/system"
"gitee.com/h79/goutils/discovery/service"
"gitee.com/h79/goutils/plugins"
"net/http"
"strings"
"sync"
"sync/atomic"
"time"
)
var _ service.Base = (*Health)(nil)
type Health struct {
conf Config
locker sync.RWMutex
nodes map[string]*Node
stopped atomic.Int32
stop chan bool
}
func New(conf Config) *Health {
if conf.MaxCount <= 0 {
conf.MaxCount = 3
}
if conf.Interval <= 0 {
conf.Interval = 30
}
return &Health{
conf: conf,
stop: make(chan bool),
nodes: make(map[string]*Node),
}
}
func (ch *Health) AddNode(id string, node *Node) {
ch.locker.Lock()
defer ch.locker.Unlock()
if _, ok := ch.nodes[id]; ok {
return
}
ch.nodes[id] = node
}
func (ch *Health) DelNode(id string) {
ch.locker.Lock()
defer ch.locker.Unlock()
delete(ch.nodes, id)
}
func (ch *Health) Start() error {
ch.stopped.Store(0)
system.ChildRunning(ch.check)
return nil
}
func (ch *Health) Stop() {
if ch.stopped.Load() >= 1 {
return
}
ch.stopped.Add(1)
ch.stop <- true
}
func (ch *Health) check() {
ticker := time.NewTicker(time.Second * ch.conf.Interval)
for {
select {
case <-ch.stop:
return
case <-ticker.C:
ch.run()
case <-system.Closed():
return
}
}
}
func (ch *Health) run() {
nodes := make(map[string]*Node)
ch.locker.RLock()
for id, node := range ch.nodes {
nodes[id] = node
}
ch.locker.RUnlock()
for _, node := range nodes {
if err := ch.checkNode(node); err != nil {
node.errCount++
logger.Error("Health: check failure, err= '%v'", err)
} else {
node.errCount = 0
}
if node.errCount > ch.conf.MaxCount {
logger.Error("Health: check failure, err count > max count(%v)", node.errCount, ch.conf.MaxCount)
//报警
ch.alarm(node)
}
}
}
func (ch *Health) alarm(node *Node) {
if !ch.conf.EnableAlarm {
return
}
d := debug.New(result.ErrTimeout).
WithDetailFormat("Health: node health check error, node= %+v", node).
WithLevel(debug.DImportantLevel)
_ = plugins.DoWithError(plugins.KAlarm, d)
}
func (ch *Health) checkNode(node *Node) error {
if node.Check != nil {
return node.Check(node)
}
if strings.Contains(node.Health.Protocol, "http") {
return ch.http(node)
}
return result.RErrNotSupport
}
func (ch *Health) http(node *Node) error {
hp := commonhttp.Http{}
body, err := hp.Do(node.Health.Method, node.URL(), nil, func(h *http.Header) {
})
if err != nil {
return err
}
if node.Unpack != nil {
return node.Unpack(body, node)
}
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/h79/goutils.git
git@gitee.com:h79/goutils.git
h79
goutils
goutils
v1.8.30

搜索帮助