diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index eb42bb06..4f7443b3 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -886,6 +886,28 @@ ribbon: clients: client1, client2, client3 ---- +[[how-to-configure-hystrix-thread-pools]] +=== How to Configure Hystrix thread pools +If you change `zuul.ribbonIsolationStrategy` to THREAD, the thread isolation strategy for Hystrix will be used for all routes. In this case, the HystrixThreadPoolKey is set to "RibbonCommand" as default. It means that HystrixCommands for all routes will be executed in the same Hystrix thread pool. This behavior can be changed using the following configuration and it will result in HystrixCommands being executed in the Hystrix thread pool for each route. + +.application.yml +---- +zuul: + threadPool: + useSeparateThreadPools: true +---- + +The default HystrixThreadPoolKey in this case is same with service ID for each route. To add a prefix to HystrixThreadPoolKey, set `zuul.threadPool.threadPoolKeyPrefix` to a value that you want to add. For example: + +.application.yml +---- +zuul: + threadPool: + useSeparateThreadPools: true + threadPoolKeyPrefix: zuulgw +---- + + [[spring-cloud-feign]] == Declarative REST Client: Feign diff --git a/pom.xml b/pom.xml index 135a3658..2b38982c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ ${basedir} 4.0.27.Final 2.7.3 - 1.2.3.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT 1.4.0.BUILD-SNAPSHOT Ditmars.BUILD-SNAPSHOT diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java index 559dbf00..073eec02 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/hystrix/HystrixConstants.java @@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.hystrix; /** * @author Spencer Gibb */ -public interface HystrixConstants { +public class HystrixConstants { - String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream"; + public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream"; + + private HystrixConstants() { + throw new AssertionError("Must not instantiate constant utility class"); + } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/metrics/RestTemplateUrlTemplateCapturingAspect.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/metrics/RestTemplateUrlTemplateCapturingAspect.java index ef353efe..18abe558 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/metrics/RestTemplateUrlTemplateCapturingAspect.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/metrics/RestTemplateUrlTemplateCapturingAspect.java @@ -26,7 +26,7 @@ import org.aspectj.lang.annotation.Aspect; @Aspect public class RestTemplateUrlTemplateCapturingAspect { @Around("execution(* org.springframework.web.client.RestOperations+.*(String, ..))") - Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable { + public Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable { try { String urlTemplate = (String) joinPoint.getArgs()[0]; RestTemplateUrlTemplateHolder.setRestTemplateUrlTemplate(urlTemplate); 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 8c2d40ad..0f1d3f34 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 @@ -160,6 +160,8 @@ public class ZuulProperties { private ExecutionIsolationStrategy ribbonIsolationStrategy = SEMAPHORE; private HystrixSemaphore semaphore = new HystrixSemaphore(); + + private HystrixThreadPool threadPool = new HystrixThreadPool(); public Set getIgnoredHeaders() { Set ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders); @@ -357,6 +359,39 @@ public class ZuulProperties { } + public static class HystrixThreadPool { + /** + * Flag to determine whether RibbonCommands should use separate thread pools for hystrix. + * By setting to true, RibbonCommands will be executed in a hystrix's thread pool that it is associated with. + * Each RibbonCommand will be associated with a thread pool according to its commandKey (serviceId). + * As default, all commands will be executed in a single thread pool whose threadPoolKey is "RibbonCommand". + * This property is only applicable when using THREAD as ribbonIsolationStrategy + */ + private boolean useSeparateThreadPools = false; + + /** + * A prefix for HystrixThreadPoolKey of hystrix's thread pool that is allocated to each service Id. + * This property is only applicable when using THREAD as ribbonIsolationStrategy and useSeparateThreadPools = true + */ + private String threadPoolKeyPrefix = ""; + + public boolean isUseSeparateThreadPools() { + return useSeparateThreadPools; + } + + public void setUseSeparateThreadPools(boolean useSeparateThreadPools) { + this.useSeparateThreadPools = useSeparateThreadPools; + } + + public String getThreadPoolKeyPrefix() { + return threadPoolKeyPrefix; + } + + public void setThreadPoolKeyPrefix(String threadPoolKeyPrefix) { + this.threadPoolKeyPrefix = threadPoolKeyPrefix; + } + } + 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/support/AbstractRibbonCommand.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java index 3c157929..5431405e 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java @@ -34,6 +34,7 @@ import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; +import com.netflix.hystrix.HystrixThreadPoolKey; import com.netflix.zuul.constants.ZuulConstants; import com.netflix.zuul.context.RequestContext; @@ -78,6 +79,9 @@ public abstract class AbstractRibbonCommand