diff options
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 13 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/circuitbreaker.go | 157 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/healthchecks.go | 3 |
4 files changed, 2 insertions, 172 deletions
@@ -24,7 +24,6 @@ require ( github.com/smallstep/certificates v0.14.2 github.com/smallstep/cli v0.14.2 github.com/smallstep/truststore v0.9.5 - github.com/vulcand/oxy v1.1.0 github.com/yuin/goldmark v1.1.28 github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 go.uber.org/zap v1.14.1 @@ -161,8 +161,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.2 h1:VBodKICVPnwmDxstcW3biKcDSpFIfS/RELUXsZSBYK4= github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -375,10 +373,8 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= @@ -477,11 +473,6 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f/go.mod h1:V3EvCedtJTvUYzJF2GZMRB0JMlai+6cBu3VCTQz33GQ= -github.com/mailgun/multibuf v0.0.0-20150714184110-565402cd71fb/go.mod h1:E0vRBBIQUHcRtmL/oR6w/jehh4FJqJFxe86gBnw9gXc= -github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAFr1YToMs98dbCdhootQ1hZIvZU28hAQ= -github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHbhWwIz3z9eVmQ2rx82rulEMG0t+Q1bzfc9DYN4= -github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f/go.mod h1:8heskWJ5c0v5J9WH89ADhyal1DOZcayll8fSbhB+/9A= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.3.1/go.mod h1:zoCNXiJnyM03LlBgTsWv8mq28s7aTC71UgKasqRJHww= github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= @@ -774,9 +765,6 @@ github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOV github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vulcand/oxy v1.1.0 h1:DbBijGo1+6cFqR9jarkMxasdj0lgWwrrFtue6ijek4Q= -github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY= -github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= github.com/vultr/govultr v0.1.4 h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U= github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= @@ -1203,7 +1191,6 @@ howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqp howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= howett.net/plist v0.0.0-20200225050739-77e249a2e2ba h1:HiEs/6jQFMHpFqsdPBAk3ieVcsSS8IV+D93f43UuDPo= howett.net/plist v0.0.0-20200225050739-77e249a2e2ba/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY= diff --git a/modules/caddyhttp/reverseproxy/circuitbreaker.go b/modules/caddyhttp/reverseproxy/circuitbreaker.go deleted file mode 100644 index 830ab43..0000000 --- a/modules/caddyhttp/reverseproxy/circuitbreaker.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2015 Matthew Holt and The Caddy Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package reverseproxy - -import ( - "fmt" - "sync/atomic" - "time" - - "github.com/caddyserver/caddy/v2" - "github.com/vulcand/oxy/memmetrics" -) - -func init() { - caddy.RegisterModule(internalCircuitBreaker{}) -} - -// internalCircuitBreaker implements circuit breaking functionality -// for requests within this process over a sliding time window. -type internalCircuitBreaker struct { - tripped int32 - cbFactor int32 - threshold float64 - metrics *memmetrics.RTMetrics - tripTime time.Duration - Config -} - -// CaddyModule returns the Caddy module information. -func (internalCircuitBreaker) CaddyModule() caddy.ModuleInfo { - return caddy.ModuleInfo{ - ID: "http.reverse_proxy.circuit_breakers.internal", - New: func() caddy.Module { return new(internalCircuitBreaker) }, - } -} - -// Provision sets up a configured circuit breaker. -func (c *internalCircuitBreaker) Provision(ctx caddy.Context) error { - f, ok := typeCB[c.Factor] - if !ok { - return fmt.Errorf("type is not defined") - } - - if c.TripTime == "" { - c.TripTime = defaultTripTime - } - - tw, err := time.ParseDuration(c.TripTime) - if err != nil { - return fmt.Errorf("cannot parse trip_time duration, %v", err.Error()) - } - - mt, err := memmetrics.NewRTMetrics() - if err != nil { - return fmt.Errorf("cannot create new metrics: %v", err.Error()) - } - - c.cbFactor = f - c.tripTime = tw - c.threshold = c.Threshold - c.metrics = mt - c.tripped = 0 - - return nil -} - -// Ok returns whether the circuit breaker is tripped or not. -func (c *internalCircuitBreaker) Ok() bool { - tripped := atomic.LoadInt32(&c.tripped) - return tripped == 0 -} - -// RecordMetric records a response status code and execution time of a request. This function should be run in a separate goroutine. -func (c *internalCircuitBreaker) RecordMetric(statusCode int, latency time.Duration) { - c.metrics.Record(statusCode, latency) - c.checkAndSet() -} - -// Ok checks our metrics to see if we should trip our circuit breaker, or if the fallback duration has completed. -func (c *internalCircuitBreaker) checkAndSet() { - var isTripped bool - - 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 factorLatency: - // check if threshold in milliseconds is reached and trip - hist, err := c.metrics.LatencyHistogram() - if err != nil { - return - } - - l := hist.LatencyAtQuantile(c.threshold) - if l.Nanoseconds()/int64(time.Millisecond) > int64(c.threshold) { - isTripped = true - } - 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 - } - } - - if isTripped { - c.metrics.Reset() - atomic.AddInt32(&c.tripped, 1) - - // wait tripTime amount before allowing operations to resume. - t := time.NewTimer(c.tripTime) - <-t.C - - atomic.AddInt32(&c.tripped, -1) - } -} - -// 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"` - // 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 ( - factorLatency = iota + 1 - factorErrorRatio - factorStatusCodeRatio - defaultTripTime = "5s" -) - -var ( - // typeCB handles converting a Config Factor value to the internal circuit breaker types. - typeCB = map[string]int32{ - "latency": factorLatency, - "error_ratio": factorErrorRatio, - "status_ratio": factorStatusCodeRatio, - } -) diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go index 85274c6..02d8438 100644 --- a/modules/caddyhttp/reverseproxy/healthchecks.go +++ b/modules/caddyhttp/reverseproxy/healthchecks.go @@ -113,7 +113,8 @@ type PassiveHealthChecks struct { // CircuitBreaker is a type that can act as an early-warning // system for the health checker when backends are getting -// overloaded. +// overloaded. This interface is still experimental and is +// subject to change. type CircuitBreaker interface { OK() bool RecordMetric(statusCode int, latency time.Duration) |