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`
This commit is contained in:
Mohammed Al Sahaf 2020-01-19 04:42:56 +03:00 committed by Matt Holt
parent 372540f0ee
commit 2bfaf8e896
2 changed files with 24 additions and 16 deletions

View file

@ -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,
}
)

View file

@ -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"`
}