diff --git a/docs/toml.md b/docs/toml.md index e0561657c..2e48c4667 100644 --- a/docs/toml.md +++ b/docs/toml.md @@ -861,6 +861,8 @@ Additional settings can be defined using Consul Catalog tags: - `traefik.backend.weight=10`: assign this weight to the container - `traefik.backend.circuitbreaker=NetworkErrorRatio() > 0.5` - `traefik.backend.loadbalancer=drr`: override the default load balancing mode +- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. +- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. - `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). - `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. - `traefik.frontend.priority=10`: override default frontend priority diff --git a/provider/consul_catalog.go b/provider/consul_catalog.go index 454ee7f17..67dac8b86 100644 --- a/provider/consul_catalog.go +++ b/provider/consul_catalog.go @@ -209,12 +209,13 @@ func (provider *ConsulCatalog) getContraintTags(tags []string) []string { func (provider *ConsulCatalog) buildConfig(catalog []catalogUpdate) *types.Configuration { var FuncMap = template.FuncMap{ - "getBackend": provider.getBackend, - "getFrontendRule": provider.getFrontendRule, - "getBackendName": provider.getBackendName, - "getBackendAddress": provider.getBackendAddress, - "getAttribute": provider.getAttribute, - "getEntryPoints": provider.getEntryPoints, + "getBackend": provider.getBackend, + "getFrontendRule": provider.getFrontendRule, + "getBackendName": provider.getBackendName, + "getBackendAddress": provider.getBackendAddress, + "getAttribute": provider.getAttribute, + "getEntryPoints": provider.getEntryPoints, + "hasMaxconnAttributes": provider.hasMaxconnAttributes, } allNodes := []*api.ServiceEntry{} @@ -249,6 +250,15 @@ func (provider *ConsulCatalog) buildConfig(catalog []catalogUpdate) *types.Confi return configuration } +func (provider *ConsulCatalog) hasMaxconnAttributes(attributes []string) bool { + amount := provider.getAttribute("backend.maxconn.amount", attributes, "") + extractorfunc := provider.getAttribute("backend.maxconn.extractorfunc", attributes, "") + if amount != "" && extractorfunc != "" { + return true + } + return false +} + func (provider *ConsulCatalog) getNodes(index map[string][]string) ([]catalogUpdate, error) { visited := make(map[string]bool) diff --git a/provider/consul_catalog_test.go b/provider/consul_catalog_test.go index f83e353af..d6d41207d 100644 --- a/provider/consul_catalog_test.go +++ b/provider/consul_catalog_test.go @@ -212,6 +212,8 @@ func TestConsulCatalogBuildConfig(t *testing.T) { "traefik.backend.loadbalancer=drr", "traefik.backend.circuitbreaker=NetworkErrorRatio() > 0.5", "random.foo=bar", + "traefik.backend.maxconn.amount=1000", + "traefik.backend.maxconn.extractorfunc=client.ip", }, }, Nodes: []*api.ServiceEntry{ @@ -260,6 +262,10 @@ func TestConsulCatalogBuildConfig(t *testing.T) { LoadBalancer: &types.LoadBalancer{ Method: "drr", }, + MaxConn: &types.MaxConn{ + Amount: 1000, + ExtractorFunc: "client.ip", + }, }, }, }, diff --git a/templates/consul_catalog.tmpl b/templates/consul_catalog.tmpl index cac301bbd..546132c81 100644 --- a/templates/consul_catalog.tmpl +++ b/templates/consul_catalog.tmpl @@ -23,6 +23,13 @@ [backends."backend-{{$service}}".loadbalancer] method = "{{$loadBalancer}}" {{end}} + + {{if hasMaxconnAttributes .Attributes}} + [backends."backend-{{$service}}".maxconn] + amount = {{getAttribute "backend.maxconn.amount" .Attributes "" }} + extractorfunc = "{{getAttribute "backend.maxconn.extractorfunc" .Attributes "" }}" + {{end}} + {{end}} [frontends]