diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 8e7a56c3..b70d3193 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1033,6 +1033,8 @@ http://www.slideshare.net/MikeyCohen1/edge-architecture-ieee-international-confe Zuul's rule engine allows rules and filters to be written in essentially any JVM language, with built in support for Java and Groovy. +NOTE: The configuration property `zuul.max.host.connections` has been replaced by two new properties, `zuul.host.maxTotalConnections` and `zuul.host.maxPerRouteConnections` which default to 200 and 20 respectively. + [[netflix-zuul-reverse-proxy]] === Embedded Zuul Reverse Proxy diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java index f0774c7c..db8976a3 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java @@ -30,6 +30,7 @@ import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; import org.springframework.cloud.netflix.zuul.filters.RouteLocator; +import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; import org.springframework.cloud.netflix.zuul.filters.discovery.ServiceRouteMapper; import org.springframework.cloud.netflix.zuul.filters.discovery.SimpleServiceRouteMapper; @@ -105,8 +106,8 @@ public class ZuulProxyConfiguration extends ZuulConfiguration { } @Bean - public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper) { - return new SimpleHostRoutingFilter(helper); + public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties zuulProperties) { + return new SimpleHostRoutingFilter(helper, zuulProperties); } @Bean diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java index ea135a73..b9f4ae99 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java @@ -70,6 +70,8 @@ public class ZuulProperties { private boolean ignoreLocalService = true; + private Host host = new Host(); + public Set getIgnoredHeaders() { Set ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders); if (ClassUtils.isPresent( @@ -170,6 +172,14 @@ public class ZuulProperties { } + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Host { + private int maxTotalConnections = 200; + private int maxPerRouteConnections = 20; + } + public String getServletPattern() { String path = this.servletPath; if (!path.startsWith("/")) { diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java index da9382ba..83013f2a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java @@ -64,6 +64,8 @@ import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; +import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.Host; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -91,6 +93,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter { "SimpleHostRoutingFilter.connectionManagerTimer", true); private ProxyRequestHelper helper; + private Host hostProperties; private PoolingHttpClientConnectionManager connectionManager; private CloseableHttpClient httpClient; @@ -107,12 +110,9 @@ public class SimpleHostRoutingFilter extends ZuulFilter { } }; - public SimpleHostRoutingFilter() { - this(new ProxyRequestHelper()); - } - - public SimpleHostRoutingFilter(ProxyRequestHelper helper) { + public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties) { this.helper = helper; + this.hostProperties = properties.getHost(); } @PostConstruct @@ -209,10 +209,9 @@ public class SimpleHostRoutingFilter extends ZuulFilter { .build(); this.connectionManager = new PoolingHttpClientConnectionManager(registry); - this.connectionManager.setMaxTotal(Integer - .parseInt(System.getProperty("zuul.max.host.connections", "200"))); - this.connectionManager.setDefaultMaxPerRoute(Integer - .parseInt(System.getProperty("zuul.max.host.connections", "20"))); + this.connectionManager.setMaxTotal(hostProperties.getMaxTotalConnections()); + this.connectionManager + .setDefaultMaxPerRoute(hostProperties.getMaxPerRouteConnections()); return this.connectionManager; } catch (Exception ex) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java index 24129e46..1026165b 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/CustomHostRoutingFilterTests.java @@ -189,14 +189,18 @@ class SampleCustomZuulProxyApplication { @Configuration @EnableZuulProxy protected static class CustomZuulProxyConfig extends ZuulProxyConfiguration { + @Bean @Override public SimpleHostRoutingFilter simpleHostRoutingFilter( - ProxyRequestHelper helper) { - return new CustomHostRoutingFilter(); + ProxyRequestHelper helper, ZuulProperties zuulProperties) { + return new CustomHostRoutingFilter(helper, zuulProperties); } private class CustomHostRoutingFilter extends SimpleHostRoutingFilter { + public CustomHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties zuulProperties) { + super(helper, zuulProperties); + } @Override public Object run() { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java new file mode 100644 index 00000000..c2470fbb --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java @@ -0,0 +1,84 @@ +/* + * Copyright 2013-2016 the original author or 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 org.springframework.cloud.netflix.zuul.filters.route; + +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; +import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.junit.Assert.assertEquals; +import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment; + +/** + * @author Andreas Kluth + * @author Spencer Gibb + */ +public class SimpleHostRoutingFilterTests { + + private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + @After + public void clear() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void connectionPropertiesAreApplied() { + addEnvironment(this.context, "zuul.host.maxTotalConnections=100", "zuul.host.maxPerRouteConnections=10"); + setupContext(); + PoolingHttpClientConnectionManager connMgr = getFilter().newConnectionManager(); + assertEquals(100, connMgr.getMaxTotal()); + assertEquals(10, connMgr.getDefaultMaxPerRoute()); + } + + @Test + public void defaultPropertiesAreApplied() { + setupContext(); + PoolingHttpClientConnectionManager connMgr = getFilter().newConnectionManager(); + + assertEquals(200, connMgr.getMaxTotal()); + assertEquals(20, connMgr.getDefaultMaxPerRoute()); + } + + private void setupContext() { + this.context.register(PropertyPlaceholderAutoConfiguration.class, + TestConfiguration.class); + this.context.refresh(); + } + + private SimpleHostRoutingFilter getFilter() { + return this.context.getBean(SimpleHostRoutingFilter.class); + } + + @Configuration + @EnableConfigurationProperties(ZuulProperties.class) + protected static class TestConfiguration { + @Bean + SimpleHostRoutingFilter simpleHostRoutingFilter(ZuulProperties zuulProperties) { + return new SimpleHostRoutingFilter(new ProxyRequestHelper(), zuulProperties); + } + } +}