完成health_check_http

This commit is contained in:
chenjiekun
2021-07-21 12:45:10 +08:00
parent 1b6fc491fc
commit c2a4535f94
10 changed files with 213 additions and 359 deletions

View File

@@ -1,25 +0,0 @@
package health_check_http
import "github.com/eolinker/goku-eosc/discovery"
type Agent struct {
agentId string
*HttpCheck
}
func NewAgent(agentId string) *Agent {
return &Agent{agentId: agentId}
}
func (a *Agent) AddToCheck(node discovery.INode) error {
a.addToCheck(&checkNode{
node: node,
agentId: a.agentId,
})
return nil
}
func (a *Agent) Stop() error {
a.stop(a.agentId)
return nil
}

View File

@@ -1,77 +0,0 @@
package health_check_http
//
//type checker struct {
// ctx context.Context
// cancelFunc context.CancelFunc
// ch chan *checkNode
// config *Config
// id string
//}
//
//func (c *checker) doCheckLoop() {
// nodes := make(map[string]map[string]discovery.INode)
// for {
// select {
// case <-c.ctx.Done():
// {
// return
// }
// case n, ok := <-c.ch:
// {
//
// }
// }
// }
//}
//
//func (c *checker) AddToCheck(node discovery.INode) error {
// n := &checkNode{
// node: node,
// from: c.id,
// }
// c.ch <- n
// return nil
//}
//
//func (c *checker) Stop() error {
// c.cancelFunc()
// return nil
//}
//
//type checkNode struct {
// node discovery.INode
// from string
//}
//
//func NewHealthCheck(conf interface{}) (discovery.IHealthChecker, error) {
// ctx, cancel := context.WithCancel(context.Background())
// ch := make(chan *checkNode, 10)
// c := &checker{
// ctx: ctx,
// cancelFunc: cancel,
// ch: ch,
// }
// return c, nil
//}
//
//func (c *checker) check() error {
// for _, checkNode := range c.nodes {
// uri := fmt.Sprintf("%s://%s/%s", c.config.Protocol, strings.TrimSuffix(checkNode.checkNode.Addr(), "/"), strings.TrimPrefix(c.config.URL, "/"))
// c.client.Timeout = c.config.Timeout
// request, err := http.NewRequest(c.config.Method, uri, nil)
// if err != nil {
// return err
// }
// resp, err := c.client.Do(request)
// if err != nil {
// return err
// }
// defer resp.Body.Close()
// if c.config.SuccessCode != resp.StatusCode {
// return errors.New("error status code")
// }
//
// }
// return nil
//}

View File

@@ -1,108 +0,0 @@
package health_check_http
//var supportMethods = []string{
// "POST", "GET", "PUT", "DELETE", "OPTIONS", "HEAD", "OPTIONS",
//}
//
//type checkerFactory struct {
// c chan *checkNode
// ctx context.Context
// cancelFunc context.CancelFunc
//}
//
//type checkNode struct {
// checkNode discovery.INode
// from string
// IsRemove bool
//}
//
//func NewCheckerFactory() *checkerFactory {
//
// ctx, cancelFunc := context.WithCancel(context.Background())
// ch := make(chan *checkNode, 10)
//
// c := checkerFactory{
// c: ch,
// ctx: ctx,
// cancelFunc: cancelFunc,
// }
// go c.doCheckLoop()
// return &c
//}
//func (c *checkerFactory) doCheckLoop() {
// for {
// select {
// case <-c.ctx.Done():
// {
// return
// }
// case checkNode, ok := <-c.c:
// {
//
// }
//
// }
// }
//}
//func (c *checkerFactory) Create(config interface{}) (discovery.IHealthChecker, error) {
// cfg, ok := config.(*Config)
// if !ok {
// return nil, errors.New("fail to create health checker")
// }
// validMethod := false
// for _, method := range supportMethods {
// if method == cfg.Method {
// validMethod = true
// break
// }
// }
// if !validMethod {
// return nil, errors.New("error request method")
// }
// return &checker{config: cfg, client: &http.Client{}}, nil
//}
//
//type checker struct {
// id string
// config *Config
// client *http.Client
// nodes map[string]*checkNode
//
// ch chan *checkNode
//}
//
//func (c *checker) AddToCheck(checkNode discovery.INode) error {
// n := &checkNode{
// checkNode: checkNode,
// from: c.id,
// }
// c.ch <- n
// c.nodes[checkNode.ID()] = n
// return nil
//}
//
//func (c *checker) Stop() error {
//
// return nil
//}
//
//func (c *checker) check() error {
// for _, checkNode := range c.nodes {
// uri := fmt.Sprintf("%s://%s/%s", c.config.Protocol, strings.TrimSuffix(checkNode.checkNode.Addr(), "/"), strings.TrimPrefix(c.config.URL, "/"))
// c.client.Timeout = c.config.Timeout
// request, err := http.NewRequest(c.config.Method, uri, nil)
// if err != nil {
// return err
// }
// resp, err := c.client.Do(request)
// if err != nil {
// return err
// }
// defer resp.Body.Close()
// if c.config.SuccessCode != resp.StatusCode {
// return errors.New("error status code")
// }
//
// }
// return nil
//}

View File

@@ -1,12 +0,0 @@
package health_check_http
import "time"
type Config struct {
Protocol string
Method string
Url string
SuccessCode int
Period time.Duration
Timeout time.Duration
}

View File

@@ -1,142 +0,0 @@
package health_check_http
import (
"context"
"fmt"
"net/http"
"strings"
"sync"
"time"
"github.com/eolinker/eosc/log"
"github.com/eolinker/goku-eosc/discovery"
"github.com/go-basic/uuid"
)
func NewHttpCheck(config Config) *HttpCheck {
ctx, cancel := context.WithCancel(context.Background())
checker := &HttpCheck{
config: &config,
ctx: ctx,
cancel: cancel,
ch: make(chan *checkNode, 10),
client: &http.Client{},
locker: sync.RWMutex{},
}
go checker.doCheckLoop()
return checker
}
type HttpCheck struct {
config *Config
ctx context.Context
cancel context.CancelFunc
ch chan *checkNode
delCh chan string
client *http.Client
locker sync.RWMutex
}
func (h *HttpCheck) doCheckLoop() {
ticker := time.NewTicker(h.config.Period)
nodes := map[string]map[string]*checkNode{}
defer ticker.Stop()
for {
select {
case <-h.ctx.Done():
return
case <-ticker.C:
{
nodes = h.check(nodes)
}
case node, ok := <-h.ch:
{
if ok {
if _, ok := nodes[node.agentId]; !ok {
nodes[node.agentId] = make(map[string]*checkNode)
}
nodes[node.agentId][node.node.ID()] = node
}
}
case id, ok := <-h.delCh:
{
if ok {
delete(nodes, id)
}
}
}
}
}
func (h *HttpCheck) Agent() (discovery.IHealthChecker, error) {
return NewAgent(uuid.New()), nil
}
func (h *HttpCheck) Reset(conf Config) error {
h.config = &conf
return nil
}
func (h *HttpCheck) AddToCheck(node discovery.INode) error {
h.addToCheck(&checkNode{
node: node,
agentId: "",
})
return nil
}
func (h *HttpCheck) addToCheck(node *checkNode) error {
h.ch <- node
return nil
}
func (h *HttpCheck) Stop() error {
h.cancel()
return nil
}
func (h *HttpCheck) stop(id string) {
h.delCh <- id
}
func (h *HttpCheck) check(nodes map[string]map[string]*checkNode) map[string]map[string]*checkNode {
newNodes := make(map[string][]*checkNode)
for _, ns := range nodes {
for _, n := range ns {
if n.node.Status() == discovery.Down {
newNodes[n.node.Addr()] = append(newNodes[n.node.Addr()], n)
}
}
}
for addr, ns := range newNodes {
uri := fmt.Sprintf("%s://%s/%s", h.config.Protocol, strings.TrimSuffix(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)
continue
}
resp, err := h.client.Do(request)
if err != nil {
log.Error(err)
continue
}
resp.Body.Close()
if h.config.SuccessCode != resp.StatusCode {
log.Error(err)
continue
}
for _, n := range ns {
n.node.Up()
delete(nodes[n.agentId], n.node.ID())
}
}
return nodes
}
type checkNode struct {
node discovery.INode
agentId string
}