mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-16 21:56:40 -05:00
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:
parent
372540f0ee
commit
2bfaf8e896
2 changed files with 24 additions and 16 deletions
|
@ -31,7 +31,7 @@ func init() {
|
||||||
// for requests within this process over a sliding time window.
|
// for requests within this process over a sliding time window.
|
||||||
type localCircuitBreaker struct {
|
type localCircuitBreaker struct {
|
||||||
tripped int32
|
tripped int32
|
||||||
cbType int32
|
cbFactor int32
|
||||||
threshold float64
|
threshold float64
|
||||||
metrics *memmetrics.RTMetrics
|
metrics *memmetrics.RTMetrics
|
||||||
tripTime time.Duration
|
tripTime time.Duration
|
||||||
|
@ -48,7 +48,7 @@ func (localCircuitBreaker) CaddyModule() caddy.ModuleInfo {
|
||||||
|
|
||||||
// Provision sets up a configured circuit breaker.
|
// Provision sets up a configured circuit breaker.
|
||||||
func (c *localCircuitBreaker) Provision(ctx caddy.Context) error {
|
func (c *localCircuitBreaker) Provision(ctx caddy.Context) error {
|
||||||
t, ok := typeCB[c.Type]
|
f, ok := typeCB[c.Factor]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("type is not defined")
|
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())
|
return fmt.Errorf("cannot create new metrics: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
c.cbType = t
|
c.cbFactor = f
|
||||||
c.tripTime = tw
|
c.tripTime = tw
|
||||||
c.threshold = c.Threshold
|
c.threshold = c.Threshold
|
||||||
c.metrics = mt
|
c.metrics = mt
|
||||||
|
@ -92,13 +92,13 @@ func (c *localCircuitBreaker) RecordMetric(statusCode int, latency time.Duration
|
||||||
func (c *localCircuitBreaker) checkAndSet() {
|
func (c *localCircuitBreaker) checkAndSet() {
|
||||||
var isTripped bool
|
var isTripped bool
|
||||||
|
|
||||||
switch c.cbType {
|
switch c.cbFactor {
|
||||||
case typeErrorRatio:
|
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
|
// 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 {
|
if c.metrics.NetworkErrorRatio() > c.threshold {
|
||||||
isTripped = true
|
isTripped = true
|
||||||
}
|
}
|
||||||
case typeLatency:
|
case factorLatency:
|
||||||
// check if threshold in milliseconds is reached and trip
|
// check if threshold in milliseconds is reached and trip
|
||||||
hist, err := c.metrics.LatencyHistogram()
|
hist, err := c.metrics.LatencyHistogram()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,7 +109,7 @@ func (c *localCircuitBreaker) checkAndSet() {
|
||||||
if l.Nanoseconds()/int64(time.Millisecond) > int64(c.threshold) {
|
if l.Nanoseconds()/int64(time.Millisecond) > int64(c.threshold) {
|
||||||
isTripped = true
|
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
|
// 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 {
|
if c.metrics.ResponseCodeRatio(500, 600, 0, 600) > c.threshold {
|
||||||
isTripped = true
|
isTripped = true
|
||||||
|
@ -130,23 +130,28 @@ func (c *localCircuitBreaker) checkAndSet() {
|
||||||
|
|
||||||
// Config represents the configuration of a circuit breaker.
|
// Config represents the configuration of a circuit breaker.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
// The threshold over sliding window that would trip the circuit breaker
|
||||||
Threshold float64 `json:"threshold"`
|
Threshold float64 `json:"threshold"`
|
||||||
Type string `json:"type"`
|
// Possible values: latency, error_ratio, and status_ratio. It
|
||||||
TripTime string `json:"trip_time"`
|
// 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 (
|
const (
|
||||||
typeLatency = iota + 1
|
factorLatency = iota + 1
|
||||||
typeErrorRatio
|
factorErrorRatio
|
||||||
typeStatusCodeRatio
|
factorStatusCodeRatio
|
||||||
defaultTripTime = "5s"
|
defaultTripTime = "5s"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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{
|
typeCB = map[string]int32{
|
||||||
"latency": typeLatency,
|
"latency": factorLatency,
|
||||||
"error_ratio": typeErrorRatio,
|
"error_ratio": factorErrorRatio,
|
||||||
"status_ratio": typeStatusCodeRatio,
|
"status_ratio": factorStatusCodeRatio,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -78,6 +78,8 @@ func (r RandomSelection) Select(pool UpstreamPool, request *http.Request) *Upstr
|
||||||
// two or more available hosts at random, then
|
// two or more available hosts at random, then
|
||||||
// chooses the one with the least load.
|
// chooses the one with the least load.
|
||||||
type RandomChoiceSelection struct {
|
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"`
|
Choose int `json:"choose,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,6 +285,7 @@ func (URIHashSelection) Select(pool UpstreamPool, req *http.Request) *Upstream {
|
||||||
// HeaderHashSelection is a policy that selects
|
// HeaderHashSelection is a policy that selects
|
||||||
// a host based on a given request header.
|
// a host based on a given request header.
|
||||||
type HeaderHashSelection struct {
|
type HeaderHashSelection struct {
|
||||||
|
// The HTTP header field whose value is to be hashed and used for upstream selection.
|
||||||
Field string `json:"field,omitempty"`
|
Field string `json:"field,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue