diff options
Diffstat (limited to 'modules/caddyhttp/reverseproxy')
-rw-r--r-- | modules/caddyhttp/reverseproxy/circuitbreaker.go | 37 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go | 31 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies.go | 3 |
3 files changed, 37 insertions, 34 deletions
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/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go index dee6eb5..8c9fd38 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go @@ -81,7 +81,7 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // // php_fastcgi localhost:7777 // -// is equivalent to: +// is equivalent to a route consisting of: // // @canonicalPath { // file { @@ -104,8 +104,8 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // } // } // -// Thus, this directive produces multiple routes, each with a different -// matcher because multiple consecutive routes are necessary to support +// Thus, this directive produces multiple handlers, each with a different +// matcher because multiple consecutive hgandlers are necessary to support // the common PHP use case. If this "common" config is not compatible // with a user's PHP requirements, they can use a manual approach based // on the example above to configure it precisely as they need. @@ -114,7 +114,7 @@ func (t *Transport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // // php_fastcgi /subpath localhost:7777 // -// then the resulting routes are wrapped in a subroute that uses the +// then the resulting handlers are wrapped in a subroute that uses the // user's matcher as a prerequisite to enter the subroute. In other // words, the directive's matcher is necessary, but not sufficient. func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) { @@ -198,12 +198,13 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(rpHandler, "handler", "reverse_proxy", nil)}, } + subroute := caddyhttp.Subroute{ + Routes: caddyhttp.RouteList{redirRoute, rewriteRoute, rpRoute}, + } + // the user's matcher is a prerequisite for ours, so // wrap ours in a subroute and return that if hasUserMatcher { - subroute := caddyhttp.Subroute{ - Routes: caddyhttp.RouteList{redirRoute, rewriteRoute, rpRoute}, - } return []httpcaddyfile.ConfigValue{ { Class: "route", @@ -215,20 +216,14 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error }, nil } - // if the user did not specify a matcher, then - // we can just use our own matchers + // otherwise, return the literal subroute instead of + // individual routes, to ensure they stay together and + // are treated as a single unit, without necessarily + // creating an actual subroute in the output return []httpcaddyfile.ConfigValue{ { Class: "route", - Value: redirRoute, - }, - { - Class: "route", - Value: rewriteRoute, - }, - { - Class: "route", - Value: rpRoute, + Value: subroute, }, }, nil } 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"` } |