Files
apinto/health-check-http/http-check.go

111 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package health_check_http
import (
"context"
"fmt"
"net/http"
"strings"
"sync"
"time"
"github.com/eolinker/eosc/log"
"github.com/eolinker/apinto/discovery"
)
var (
_ discovery.IHealthChecker = (*HTTPCheck)(nil)
)
// NewHTTPCheck 创建HTTPCheck
func NewHTTPCheck(config Config) *HTTPCheck {
ctx, cancel := context.WithCancel(context.Background())
checker := &HTTPCheck{
config: &config,
ctx: ctx,
cancel: cancel,
client: &http.Client{},
locker: sync.RWMutex{},
}
return checker
}
// HTTPCheck HTTP健康检查结构,实现了IHealthChecker接口
type HTTPCheck struct {
config *Config
nodes discovery.INodes
ctx context.Context
cancel context.CancelFunc
client *http.Client
locker sync.RWMutex
}
func (h *HTTPCheck) Check(nodes discovery.INodes) {
go h.doCheckLoop(nodes)
}
// doCheckLoop 定时检查,维护了一个待检测节点集合
func (h *HTTPCheck) doCheckLoop(nodes discovery.INodes) {
if h.config.Period < 1 {
return
}
ticker := time.NewTicker(h.config.Period)
//timer := time.NewTimer(h.config.Period)
defer ticker.Stop()
for {
select {
case <-h.ctx.Done():
return
case <-ticker.C:
{
h.check(nodes)
}
}
}
}
// Stop 停止HTTPCheck中止定时检查
func (h *HTTPCheck) Stop() {
h.cancel()
}
// check 对待检查的节点集合进行检测入参nodes map[agentID][nodeID]*checkNode
func (h *HTTPCheck) check(nodes discovery.INodes) {
/*对每个节点地址进行检测
成功则将属于该地址的所有节点的状态都置于可运行并从HTTPCheck维护的待检测节点列表中移除
失败则下次定时检查再进行检测
*/
for _, ns := range nodes.All() {
//if ns.Status() != discovery.Down {
// continue
//}
uri := fmt.Sprintf("%s://%s/%s", h.config.Protocol, strings.TrimSuffix(ns.Addr(), "/"), strings.TrimPrefix(h.config.URL, "/"))
h.client.Timeout = h.config.Timeout
request, err := http.NewRequest(h.config.Method, uri, nil)
if err != nil {
log.Error(err)
ns.Down()
continue
}
resp, err := h.client.Do(request)
if err != nil {
log.Error(err)
ns.Down()
continue
}
resp.Body.Close()
if h.config.SuccessCode != resp.StatusCode {
log.Error(err)
ns.Down()
continue
}
ns.Up()
}
}