refactor: simplify health monitor code

This commit is contained in:
yusing 2025-04-10 05:03:01 +08:00
parent 5d2b700cb2
commit fb075a24d7
7 changed files with 37 additions and 44 deletions

View file

@ -44,7 +44,7 @@ func CheckHealth(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
result, err = monitor.NewHTTPHealthChecker(types.NewURL(&url.URL{
result, err = monitor.NewHTTPHealthMonitor(types.NewURL(&url.URL{
Scheme: scheme,
Host: host,
Path: path,
@ -63,7 +63,7 @@ func CheckHealth(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
result, err = monitor.NewRawHealthChecker(types.NewURL(&url.URL{
result, err = monitor.NewRawHealthMonitor(types.NewURL(&url.URL{
Scheme: scheme,
Host: host,
}), defaultHealthConfig).CheckHealth()

View file

@ -112,17 +112,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
r.handler = waker
r.HealthMon = waker
case r.UseHealthCheck():
if r.IsDocker() {
client, err := docker.NewClient(r.Container.DockerHost)
if err == nil {
fallback := r.newHealthMonitor()
r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Container.ContainerID, r.TargetName(), r.HealthCheck, fallback)
r.task.OnCancel("close_docker_client", client.Close)
}
}
if r.HealthMon == nil {
r.HealthMon = r.newHealthMonitor()
}
r.HealthMon = monitor.NewMonitor(r)
}
if r.UseAccessLog() {
@ -205,17 +195,6 @@ func (r *ReveseProxyRoute) HealthMonitor() health.HealthMonitor {
return r.HealthMon
}
func (r *ReveseProxyRoute) newHealthMonitor() interface {
health.HealthMonitor
health.HealthChecker
} {
if a := r.Agent(); a != nil {
target := monitor.AgentTargetFromURL(r.ProxyURL)
return monitor.NewAgentProxiedMonitor(a, r.HealthCheck, target)
}
return monitor.NewHTTPHealthMonitor(r.ProxyURL, r.HealthCheck)
}
func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) {
var lb *loadbalancer.LoadBalancer
cfg := r.LoadBalance

View file

@ -66,17 +66,7 @@ func (r *StreamRoute) Start(parent task.Parent) gperr.Error {
r.Stream = waker
r.HealthMon = waker
case r.UseHealthCheck():
if r.IsDocker() {
client, err := docker.NewClient(r.Container.DockerHost)
if err == nil {
fallback := monitor.NewRawHealthChecker(r.TargetURL(), r.HealthCheck)
r.HealthMon = monitor.NewDockerHealthMonitor(client, r.Container.ContainerID, r.TargetName(), r.HealthCheck, fallback)
r.task.OnCancel("close_docker_client", client.Close)
}
}
if r.HealthMon == nil {
r.HealthMon = monitor.NewRawHealthMonitor(r.TargetURL(), r.HealthCheck)
}
r.HealthMon = monitor.NewMonitor(r)
}
if err := r.Stream.Setup(); err != nil {
@ -88,7 +78,7 @@ func (r *StreamRoute) Start(parent task.Parent) gperr.Error {
if r.HealthMon != nil {
if err := r.HealthMon.Start(r.task); err != nil {
gperr.LogWarn("health monitor error", err, &r.l)
return err
}
}

View file

@ -37,10 +37,6 @@ func NewHTTPHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *HTT
return mon
}
func NewHTTPHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker {
return NewHTTPHealthMonitor(url, config)
}
func (mon *HTTPHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) {
ctx, cancel := mon.ContextWithTimeout("ping request timed out")
defer cancel()

View file

@ -6,10 +6,12 @@ import (
"fmt"
"time"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/notif"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/utils/atomic"
"github.com/yusing/go-proxy/internal/utils/strutils"
@ -35,6 +37,32 @@ type (
var ErrNegativeInterval = errors.New("negative interval")
func NewMonitor(r route.Route) health.HealthMonCheck {
var mon health.HealthMonCheck
if r.IsAgent() {
mon = NewAgentProxiedMonitor(r.Agent(), r.HealthCheckConfig(), AgentTargetFromURL(r.TargetURL()))
} else {
switch r := r.(type) {
case route.HTTPRoute:
mon = NewHTTPHealthMonitor(r.TargetURL(), r.HealthCheckConfig())
case route.StreamRoute:
mon = NewRawHealthMonitor(r.TargetURL(), r.HealthCheckConfig())
default:
logging.Panic().Msgf("unexpected route type: %T", r)
}
}
if r.IsDocker() {
cont := r.DockerContainer()
client, err := docker.NewClient(cont.DockerHost)
if err != nil {
return mon
}
r.Task().OnCancel("close_docker_client", client.Close)
return NewDockerHealthMonitor(client, cont.ContainerID, r.TargetName(), r.HealthCheckConfig(), mon)
}
return mon
}
func newMonitor(url *types.URL, config *health.HealthCheckConfig, healthCheckFunc HealthCheckFunc) *monitor {
mon := &monitor{
config: config,

View file

@ -25,10 +25,6 @@ func NewRawHealthMonitor(url *types.URL, config *health.HealthCheckConfig) *RawH
return mon
}
func NewRawHealthChecker(url *types.URL, config *health.HealthCheckConfig) health.HealthChecker {
return NewRawHealthMonitor(url, config)
}
func (mon *RawHealthMonitor) CheckHealth() (result *health.HealthCheckResult, err error) {
ctx, cancel := mon.ContextWithTimeout("ping request timed out")
defer cancel()

View file

@ -34,4 +34,8 @@ type (
Config() *HealthCheckConfig
UpdateURL(url *types.URL)
}
HealthMonCheck interface {
HealthMonitor
HealthChecker
}
)