From 2c61b50b5f4d206ea714d7b6e99e10b51ca01aed Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Sat, 15 Apr 2023 08:44:12 -0400 Subject: [PATCH] Add `min_successes` --- modules/caddyhttp/reverseproxy/caddyfile.go | 17 +++++++++++++++++ modules/caddyhttp/reverseproxy/healthchecks.go | 8 ++++++++ modules/caddyhttp/reverseproxy/reverseproxy.go | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/modules/caddyhttp/reverseproxy/caddyfile.go b/modules/caddyhttp/reverseproxy/caddyfile.go index c12fb2ec0..119f433df 100644 --- a/modules/caddyhttp/reverseproxy/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/caddyfile.go @@ -79,6 +79,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) // max_fails // success_duration // min_success_ratio +// min_success // unhealthy_status // unhealthy_latency // unhealthy_request_count @@ -456,6 +457,22 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } h.HealthChecks.Passive.MinSuccessRatio = ratio + case "min_successes": + if !d.NextArg() { + return d.ArgErr() + } + if h.HealthChecks == nil { + h.HealthChecks = new(HealthChecks) + } + if h.HealthChecks.Passive == nil { + h.HealthChecks.Passive = new(PassiveHealthChecks) + } + count, err := strconv.Atoi(d.Val()) + if err != nil { + return d.Errf("invalid minimum success count '%s': %v", d.Val(), err) + } + h.HealthChecks.Passive.MinSuccesses = count + case "fail_duration": if !d.NextArg() { return d.ArgErr() diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go index 20ba0b9bf..14782e71b 100644 --- a/modules/caddyhttp/reverseproxy/healthchecks.go +++ b/modules/caddyhttp/reverseproxy/healthchecks.go @@ -127,6 +127,14 @@ type PassiveHealthChecks struct { // must be configured for those stats to be counted. Default is 0 (no ratio). MinSuccessRatio caddyhttp.Ratio `json:"min_success_ratio,omitempty"` + // The minimum number of successful requests before considering the + // minimum success ratio. Default is 5. Requires MinSuccessRatio >= 0. + // + // If there are less than this many successful requests, then the ratio is + // ignored, because of a lack of data. This ensures that the upstream isn't + // prematurely considered unhealthy because no requests have happened yet. + MinSuccesses int `json:"min_successes,omitempty"` + // Limits the number of simultaneous requests to a backend by // marking the backend as "down" if it has this many concurrent // requests or more. diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index ad0bcfcf0..6ba98da77 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -352,6 +352,10 @@ func (h *Handler) Provision(ctx caddy.Context) error { if h.HealthChecks.Passive.FailDuration > 0 && h.HealthChecks.Passive.MaxFails == 0 { h.HealthChecks.Passive.MaxFails = 1 } + + if h.HealthChecks.Passive.MinSuccessRatio > 0 && h.HealthChecks.Passive.MinSuccesses == 0 { + h.HealthChecks.Passive.MinSuccesses = 5 + } } // if active health checks are enabled, configure them and start a worker