From 4a9e82903e50126f7e0fc086fdc8954943caf58f Mon Sep 17 00:00:00 2001 From: Emile Vauge Date: Tue, 29 Mar 2016 22:25:32 +0200 Subject: [PATCH] add retries request Signed-off-by: Emile Vauge --- README.md | 3 ++- configuration.go | 7 +++++++ docs/index.md | 20 ++++++++++++++++++++ glide.lock | 33 ++++++++++++++++++--------------- glide.yaml | 1 + server.go | 25 +++++++++++++++++++++++++ traefik.sample.toml | 20 ++++++++++++++++++++ 7 files changed, 93 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 829aa61e5..c130098a0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Træfɪk is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. -It supports several backends ([Docker :whale:](https://www.docker.com/), [Mesos/Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Zookeeper](https://zookeeper.apache.org), [BoltDB](https://github.com/boltdb/bolt), Rest API, file...) to manage its configuration automatically and dynamically. +It supports several backends ([Docker :whale:](https://www.docker.com/), [Swarm :whale: :whale:](https://docs.docker.com/swarm), [Mesos/Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Zookeeper](https://zookeeper.apache.org), [BoltDB](https://github.com/boltdb/bolt), Rest API, file...) to manage its configuration automatically and dynamically. ## Features @@ -32,6 +32,7 @@ It supports several backends ([Docker :whale:](https://www.docker.com/), [Mesos/ - Clean AngularJS Web UI - Websocket support - HTTP/2 support +- Retry request if network error - [Let's Encrypt](https://letsencrypt.org) support (Automatic HTTPS) ## Demo diff --git a/configuration.go b/configuration.go index 597c3d725..a2cfd122c 100644 --- a/configuration.go +++ b/configuration.go @@ -27,6 +27,7 @@ type GlobalConfiguration struct { DefaultEntryPoints DefaultEntryPoints ProvidersThrottleDuration time.Duration MaxIdleConnsPerHost int + Retry *Retry Docker *provider.Docker File *provider.File Web *WebProvider @@ -182,6 +183,12 @@ type Certificate struct { KeyFile string } +// Retry contains request retry config +type Retry struct { + Attempts int + MaxMem int64 +} + // NewGlobalConfiguration returns a GlobalConfiguration with default values. func NewGlobalConfiguration() *GlobalConfiguration { return new(GlobalConfiguration) diff --git a/docs/index.md b/docs/index.md index e034c6466..188104170 100644 --- a/docs/index.md +++ b/docs/index.md @@ -327,6 +327,26 @@ Use "traefik [command] --help" for more information about a command. # [entryPoints.http.redirect] # regex = "^http://localhost/(.*)" # replacement = "http://mydomain/$1" + +# Enable retry sending request if network error +# +# Optional +# +# [retry] + +# Number of attempts +# +# Optional +# Default: (number servers in backend) -1 +# +# attempts = 3 + +# Sets the maximum request body to be stored in memory in Mo +# +# Optional +# Default: 2 +# +# maxMem = 3 ``` ### Samples diff --git a/glide.lock b/glide.lock index f08dc9c1b..07939a6a6 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 7734b691c46b399a06cdcaa5d7feb77ea32e350cd4ff04dcbc73c06ef22468e6 -updated: 2016-03-27T19:57:17.213688266+02:00 +hash: 21d4e8dc80c87101568a719ecf01d1af9a1b58f03c5c9dc864a8cb1005ddc160 +updated: 2016-03-29T21:50:20.577439177+02:00 imports: - name: github.com/alecthomas/template version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0 @@ -29,6 +29,7 @@ imports: - memmetrics - roundrobin - utils + - stream - name: github.com/coreos/go-etcd version: cc90c7b091275e606ad0ca7102a23fb2072f3f5e subpackages: @@ -114,10 +115,10 @@ imports: - external/github.com/Sirupsen/logrus - external/github.com/docker/docker/pkg/idtools - external/github.com/docker/docker/pkg/ioutils - - external/github.com/docker/docker/pkg/longpath - external/github.com/docker/docker/pkg/pools - external/github.com/docker/docker/pkg/promise - external/github.com/docker/docker/pkg/system + - external/github.com/docker/docker/pkg/longpath - external/github.com/opencontainers/runc/libcontainer/user - external/golang.org/x/sys/unix - external/golang.org/x/net/context @@ -143,7 +144,7 @@ imports: subpackages: - api - name: github.com/hashicorp/hcl - version: 567a5d1c4878a4ac8c198c730fd15f978b0529c7 + version: 2604f3bda7e8960c1be1063709e7d7f0765048d0 subpackages: - hcl/ast - hcl/parser @@ -156,21 +157,23 @@ imports: - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/kr/pretty - version: e6ac2fc51e89a3249e82157fa0bb7a18ef9dd5bb + version: add1dbc86daf0f983cd4a48ceb39deb95c729b67 - name: github.com/kr/text version: bb797dc4fb8320488f47bf11de07a733d7233e1f - name: github.com/magiconair/properties - version: 497d0afefddf378f9ffb3c89db6a326985908519 + version: c265cfa48dda6474e208715ca93e987829f572f8 - name: github.com/mailgun/log version: 44874009257d4d47ba9806f1b7f72a32a015e4d8 - name: github.com/mailgun/manners version: fada45142db3f93097ca917da107aa3fad0ffcb5 +- name: github.com/mailgun/multibuf + version: 565402cd71fbd9c12aa7e295324ea357e970a61e - name: github.com/mailgun/predicate version: cb0bff91a7ab7cf7571e661ff883fc997bc554a3 - name: github.com/mailgun/timetools version: fd192d755b00c968d312d23f521eb0cdc6f66bd0 - name: github.com/miekg/dns - version: b9171237b0642de1d8e8004f16869970e065f46b + version: 7e024ce8ce18b21b475ac6baf8fa3c42536bf2fa - name: github.com/mitchellh/mapstructure version: d2dd0262208475919e1a362f675cfc0e7c10e905 - name: github.com/opencontainers/runc @@ -192,7 +195,7 @@ imports: - name: github.com/spf13/cast version: ee7b3e0353166ab1f3a605294ac8cd2b77953778 - name: github.com/spf13/cobra - version: 1bacefc9a216c93293e670067bd159a64b4d72c3 + version: c678ff029ee250b65714e518f4f5c5cb934955de subpackages: - cobra - name: github.com/spf13/jwalterweatherman @@ -201,11 +204,6 @@ imports: version: 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7 - name: github.com/spf13/viper version: a212099cbe6fbe8d07476bfda8d2d39b6ff8f325 -- name: github.com/square/go-jose - version: 70a7e670bd0d4bb35902d31f3a75a6689843abed - subpackages: - - cipher - - json - name: github.com/stretchr/objx version: cbeaeb16a013161a98496fad62933b1d21786672 - name: github.com/stretchr/testify @@ -239,11 +237,11 @@ imports: - name: github.com/wendal/errors version: f66c77a7882b399795a8987ebf87ef64a427417e - name: github.com/xenolf/lego - version: 118d9d5ec92bc243ea054742a03afae813ac1314 + version: ca19a90028e242e878585941c2a27c8f3b3efc25 subpackages: - acme - name: golang.org/x/crypto - version: 6025851c7c2bf210daf74d22300c699b16541847 + version: 9e7f5dc375abeb9619ea3c5c58502c428f457aa2 subpackages: - ocsp - name: golang.org/x/net @@ -265,6 +263,11 @@ imports: version: 22287bab4379e1fbf6002fb4eb769888f3fb224c subpackages: - bson +- name: gopkg.in/square/go-jose.v1 + version: 7d9df93c5ee8a09ed250b3b2360972fa29b4bb3c + subpackages: + - cipher + - json - name: gopkg.in/yaml.v2 version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40 devImports: [] diff --git a/glide.yaml b/glide.yaml index 0d47a1f96..77db5e230 100644 --- a/glide.yaml +++ b/glide.yaml @@ -167,3 +167,4 @@ import: - package: github.com/xenolf/lego - package: github.com/vdemeester/libkermit ref: 01a5399bdbd3312916c9fa4848108fbc81fe88d8 + - package: github.com/mailgun/multibuf diff --git a/server.go b/server.go index c911aa2e3..4f3f28489 100644 --- a/server.go +++ b/server.go @@ -14,6 +14,7 @@ import ( "reflect" "regexp" "sort" + "strconv" "sync" "syscall" "time" @@ -23,6 +24,7 @@ import ( "github.com/containous/oxy/cbreaker" "github.com/containous/oxy/forward" "github.com/containous/oxy/roundrobin" + "github.com/containous/oxy/stream" "github.com/containous/traefik/middlewares" "github.com/containous/traefik/provider" "github.com/containous/traefik/types" @@ -412,6 +414,29 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo } } } + // retry ? + if globalConfiguration.Retry != nil { + retries := len(configuration.Backends[frontend.Backend].Servers) - 1 + if globalConfiguration.Retry.Attempts > 0 { + retries = globalConfiguration.Retry.Attempts + } + maxMem := int64(2 * 1024 * 1024) + if globalConfiguration.Retry.MaxMem > 0 { + maxMem = globalConfiguration.Retry.MaxMem + } + lb, err = stream.New(lb, + stream.Logger(oxyLogger), + stream.Retry("IsNetworkError() && Attempts() < "+strconv.Itoa(retries)), + stream.MemRequestBodyBytes(maxMem), + stream.MaxRequestBodyBytes(maxMem), + stream.MemResponseBodyBytes(maxMem), + stream.MaxResponseBodyBytes(maxMem)) + log.Debugf("Creating retries max attempts %d", retries) + if err != nil { + return nil, err + } + } + var negroni = negroni.New() if configuration.Backends[frontend.Backend].CircuitBreaker != nil { log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression) diff --git a/traefik.sample.toml b/traefik.sample.toml index 4bd6a3af0..6985d55f8 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -144,6 +144,26 @@ # regex = "^http://localhost/(.*)" # replacement = "http://mydomain/$1" +# Enable retry sending request if network error +# +# Optional +# +# [retry] + +# Number of attempts +# +# Optional +# Default: (number servers in backend) -1 +# +# attempts = 3 + +# Sets the maximum request body to be stored in memory in Mo +# +# Optional +# Default: 2 +# +# maxMem = 3 + ################################################################ # Web configuration backend ################################################################