From 2bfaf8e89678fc1117984658f31f43fe90266763 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Sun, 19 Jan 2020 04:42:56 +0300 Subject: reverse_proxy: CB docs; rename type -> factor (#2986) * v2: add documentation for circuit breaker config and "random selection" load balancing policy * v2: rename circuit breaker config inline key from `type` to `breaker` to avoid json key clash between the `circuit_breaker` type and the `type` field of the generic circuit breaker Config struct used by circuit breaking implementations * v2: restore the circuit breaker inline key to `type` and rename the name circuit breaker config field from `Type` to `Factor` --- modules/caddyhttp/reverseproxy/circuitbreaker.go | 37 ++++++++++++---------- .../caddyhttp/reverseproxy/selectionpolicies.go | 3 ++ 2 files changed, 24 insertions(+), 16 deletions(-) (limited to 'modules') diff --git a/modules/caddyhttp/reverseproxy/circuitbreaker.go b/modules/caddyhttp/reverseproxy/circuitbreaker.go index 474f1c6..00b38a8 100644 --- a/modules/caddyhttp/reverseproxy/circuitbreaker.go +++ b/modules/caddyhttp/reverseproxy/circuitbreaker.go @@ -31,7 +31,7 @@ func init() { // for requests within this process over a sliding time window. type localCircuitBreaker struct { tripped int32 - cbType int32 + cbFactor int32 threshold float64 metrics *memmetrics.RTMetrics tripTime time.Duration @@ -48,7 +48,7 @@ func (localCircuitBreaker) CaddyModule() caddy.ModuleInfo { // Provision sets up a configured circuit breaker. func (c *localCircuitBreaker) Provision(ctx caddy.Context) error { - t, ok := typeCB[c.Type] + f, ok := typeCB[c.Factor] if !ok { return fmt.Errorf("type is not defined") } @@ -67,7 +67,7 @@ func (c *localCircuitBreaker) Provision(ctx caddy.Context) error { return fmt.Errorf("cannot create new metrics: %v", err.Error()) } - c.cbType = t + c.cbFactor = f c.tripTime = tw c.threshold = c.Threshold c.metrics = mt @@ -92,13 +92,13 @@ func (c *localCircuitBreaker) RecordMetric(statusCode int, latency time.Duration func (c *localCircuitBreaker) checkAndSet() { var isTripped bool - switch c.cbType { - case typeErrorRatio: + switch c.cbFactor { + case factorErrorRatio: // check if amount of network errors exceed threshold over sliding window, threshold for comparison should be < 1.0 i.e. .5 = 50th percentile if c.metrics.NetworkErrorRatio() > c.threshold { isTripped = true } - case typeLatency: + case factorLatency: // check if threshold in milliseconds is reached and trip hist, err := c.metrics.LatencyHistogram() if err != nil { @@ -109,7 +109,7 @@ func (c *localCircuitBreaker) checkAndSet() { if l.Nanoseconds()/int64(time.Millisecond) > int64(c.threshold) { isTripped = true } - case typeStatusCodeRatio: + case factorStatusCodeRatio: // check ratio of error status codes of sliding window, threshold for comparison should be < 1.0 i.e. .5 = 50th percentile if c.metrics.ResponseCodeRatio(500, 600, 0, 600) > c.threshold { isTripped = true @@ -130,23 +130,28 @@ func (c *localCircuitBreaker) checkAndSet() { // Config represents the configuration of a circuit breaker. type Config struct { + // The threshold over sliding window that would trip the circuit breaker Threshold float64 `json:"threshold"` - Type string `json:"type"` - TripTime string `json:"trip_time"` + // Possible values: latency, error_ratio, and status_ratio. It + // defaults to latency. + Factor string `json:"factor"` + // How long to wait after the circuit is tripped before allowing operations to resume. + // The default is 5s. + TripTime string `json:"trip_time"` } const ( - typeLatency = iota + 1 - typeErrorRatio - typeStatusCodeRatio + factorLatency = iota + 1 + factorErrorRatio + factorStatusCodeRatio defaultTripTime = "5s" ) var ( - // typeCB handles converting a Config Type value to the internal circuit breaker types. + // typeCB handles converting a Config Factor value to the internal circuit breaker types. typeCB = map[string]int32{ - "latency": typeLatency, - "error_ratio": typeErrorRatio, - "status_ratio": typeStatusCodeRatio, + "latency": factorLatency, + "error_ratio": factorErrorRatio, + "status_ratio": factorStatusCodeRatio, } ) diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index 937ae37..330dbdc 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -78,6 +78,8 @@ func (r RandomSelection) Select(pool UpstreamPool, request *http.Request) *Upstr // two or more available hosts at random, then // chooses the one with the least load. type RandomChoiceSelection struct { + // The size of the sub-pool created from the larger upstream pool. The default value + // is 2 and the maximum at selection time is the size of the upstream pool. Choose int `json:"choose,omitempty"` } @@ -283,6 +285,7 @@ func (URIHashSelection) Select(pool UpstreamPool, req *http.Request) *Upstream { // HeaderHashSelection is a policy that selects // a host based on a given request header. type HeaderHashSelection struct { + // The HTTP header field whose value is to be hashed and used for upstream selection. Field string `json:"field,omitempty"` } -- cgit v1.2.3