From 1d9c1975b2acaa23c97dd7c2e1232a676e126eab Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 14 Apr 2020 12:04:26 +0800 Subject: [PATCH 1/5] Polish alibaba/spring-cloud-alibaba#1363 : Sync spring-cloud-alibaba-sentinel-datasource module --- spring-cloud-alibaba-dependencies/pom.xml | 6 ++ .../pom.xml | 6 ++ .../config/ConsulDataSourceProperties.java | 97 +++++++++++++++++++ .../DataSourcePropertiesConfiguration.java | 15 +++ .../config/RedisDataSourceProperties.java | 2 +- .../ConsulDataSourceFactoryBean.java | 95 ++++++++++++++++++ .../META-INF/sentinel-datasource.properties | 1 + 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java create mode 100644 spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml index 91d2cb68..b4ee393b 100644 --- a/spring-cloud-alibaba-dependencies/pom.xml +++ b/spring-cloud-alibaba-dependencies/pom.xml @@ -89,6 +89,12 @@ ${sentinel.version} + + com.alibaba.csp + sentinel-datasource-consul + ${sentinel.version} + + com.alibaba.csp sentinel-web-servlet diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml index fda615af..ba7ecd5e 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/pom.xml @@ -83,6 +83,12 @@ true + + com.alibaba.csp + sentinel-datasource-consul + true + + com.fasterxml.jackson.core jackson-databind diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java new file mode 100644 index 00000000..5903626a --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java @@ -0,0 +1,97 @@ +/* + * Copyright 2013-2018 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 + * + * https://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 com.alibaba.cloud.sentinel.datasource.config; + +import com.alibaba.cloud.sentinel.datasource.factorybean.ConsulDataSourceFactoryBean; +import org.springframework.util.StringUtils; + +/** + * Consul Properties class Using by {@link DataSourcePropertiesConfiguration} and + * {@link ConsulDataSourceFactoryBean}. + * + * @author mengjin + */ +public class ConsulDataSourceProperties extends AbstractDataSourceProperties { + + public ConsulDataSourceProperties(){ + super(ConsulDataSourceFactoryBean.class.getName()); + } + + /** + * consul server host. + */ + private String host; + + /** + * consul server port. + */ + private int port=8500; + + /** + * data key in Redis. + */ + private String ruleKey; + + /** + * Request of query will hang until timeout (in second) or get updated value. + */ + private int waitTimeoutInSecond = 1; + + @Override + public void preCheck(String dataSourceName) { + if(StringUtils.isEmpty(host)){ + throw new IllegalArgumentException( + "ConsulDataSource server-host is empty"); + } + if(StringUtils.isEmpty(ruleKey)){ + throw new IllegalArgumentException( + "ConsulDataSource ruleKey can not be empty"); + } + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getRuleKey() { + return ruleKey; + } + + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } + + public int getWaitTimeoutInSecond() { + return waitTimeoutInSecond; + } + + public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { + this.waitTimeoutInSecond = waitTimeoutInSecond; + } +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java index 2c4f1d7b..a0a5526f 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java @@ -34,6 +34,7 @@ import org.springframework.util.ObjectUtils; * @see ZookeeperDataSourceProperties * @see FileDataSourceProperties * @see RedisDataSourceProperties + * @see ConsulDataSourceProperties */ public class DataSourcePropertiesConfiguration { @@ -47,9 +48,23 @@ public class DataSourcePropertiesConfiguration { private RedisDataSourceProperties redis; + private ConsulDataSourceProperties consul; + public DataSourcePropertiesConfiguration() { } + public DataSourcePropertiesConfiguration(ConsulDataSourceProperties consul) { + this.consul = consul; + } + + public ConsulDataSourceProperties getConsul() { + return consul; + } + + public void setConsul(ConsulDataSourceProperties consul) { + this.consul = consul; + } + public DataSourcePropertiesConfiguration(FileDataSourceProperties file) { this.file = file; } diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java index 984b6e2c..a5049660 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/RedisDataSourceProperties.java @@ -24,7 +24,7 @@ import com.alibaba.cloud.sentinel.datasource.factorybean.RedisDataSourceFactoryB import org.springframework.util.StringUtils; /** - * Zookeeper Properties class Using by {@link DataSourcePropertiesConfiguration} and + * Redis Properties class Using by {@link DataSourcePropertiesConfiguration} and * {@link RedisDataSourceFactoryBean}. * * @author lengleng diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java new file mode 100644 index 00000000..ad132357 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java @@ -0,0 +1,95 @@ +/* + * Copyright 2013-2018 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 + * + * https://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 com.alibaba.cloud.sentinel.datasource.factorybean; + +import com.alibaba.csp.sentinel.datasource.Converter; +import com.alibaba.csp.sentinel.datasource.consul.ConsulDataSource; +import org.springframework.beans.factory.FactoryBean; + +/** + * A {@link FactoryBean} for creating {@link ConsulDataSource} instance. + * + * @author mengjin + * @see ConsulDataSource + */ +public class ConsulDataSourceFactoryBean implements FactoryBean { + + private String host; + + private int port; + + private String ruleKey; + + private int waitTimeoutInSecond; + + private Converter converter; + + @Override + public ConsulDataSource getObject() throws Exception { + return new ConsulDataSource( + host, + port, + ruleKey, + waitTimeoutInSecond, + converter); + } + + @Override + public Class getObjectType() { + return ConsulDataSource.class; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getRuleKey() { + return ruleKey; + } + + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } + + public int getWaitTimeoutInSecond() { + return waitTimeoutInSecond; + } + + public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { + this.waitTimeoutInSecond = waitTimeoutInSecond; + } + + public Converter getConverter() { + return converter; + } + + public void setConverter(Converter converter) { + this.converter = converter; + } +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/resources/META-INF/sentinel-datasource.properties b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/resources/META-INF/sentinel-datasource.properties index 074751fb..e67a3b9b 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/resources/META-INF/sentinel-datasource.properties +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/resources/META-INF/sentinel-datasource.properties @@ -3,3 +3,4 @@ file =com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource apollo = com.alibaba.csp.sentinel.datasource.apollo.ApolloDataSource zk = com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource redis = com.alibaba.csp.sentinel.datasource.redis.RedisDataSource +consul = com.alibaba.csp.sentinel.datasource.consul.ConsulDataSource From d11f2a06088eb1bdec6ca5cf43a1c60caf849764 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 14 Apr 2020 13:06:28 +0800 Subject: [PATCH 2/5] Polish alibaba/spring-cloud-alibaba#1363 : Sync spring-cloud-alibaba-sentinel-datasource module --- .../config/ConsulDataSourceProperties.java | 108 +++++++++--------- .../ConsulDataSourceFactoryBean.java | 92 +++++++-------- 2 files changed, 98 insertions(+), 102 deletions(-) diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java index 5903626a..e3e68d47 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/ConsulDataSourceProperties.java @@ -17,6 +17,7 @@ package com.alibaba.cloud.sentinel.datasource.config; import com.alibaba.cloud.sentinel.datasource.factorybean.ConsulDataSourceFactoryBean; + import org.springframework.util.StringUtils; /** @@ -27,71 +28,70 @@ import org.springframework.util.StringUtils; */ public class ConsulDataSourceProperties extends AbstractDataSourceProperties { - public ConsulDataSourceProperties(){ - super(ConsulDataSourceFactoryBean.class.getName()); - } + public ConsulDataSourceProperties() { + super(ConsulDataSourceFactoryBean.class.getName()); + } - /** - * consul server host. - */ - private String host; + /** + * consul server host. + */ + private String host; - /** - * consul server port. - */ - private int port=8500; + /** + * consul server port. + */ + private int port = 8500; - /** - * data key in Redis. - */ - private String ruleKey; + /** + * data key in Redis. + */ + private String ruleKey; - /** - * Request of query will hang until timeout (in second) or get updated value. - */ - private int waitTimeoutInSecond = 1; + /** + * Request of query will hang until timeout (in second) or get updated value. + */ + private int waitTimeoutInSecond = 1; - @Override - public void preCheck(String dataSourceName) { - if(StringUtils.isEmpty(host)){ - throw new IllegalArgumentException( - "ConsulDataSource server-host is empty"); - } - if(StringUtils.isEmpty(ruleKey)){ - throw new IllegalArgumentException( - "ConsulDataSource ruleKey can not be empty"); - } - } + @Override + public void preCheck(String dataSourceName) { + if (StringUtils.isEmpty(host)) { + throw new IllegalArgumentException("ConsulDataSource server-host is empty"); + } + if (StringUtils.isEmpty(ruleKey)) { + throw new IllegalArgumentException( + "ConsulDataSource ruleKey can not be empty"); + } + } - public String getHost() { - return host; - } + public String getHost() { + return host; + } - public void setHost(String host) { - this.host = host; - } + public void setHost(String host) { + this.host = host; + } - public int getPort() { - return port; - } + public int getPort() { + return port; + } - public void setPort(int port) { - this.port = port; - } + public void setPort(int port) { + this.port = port; + } - public String getRuleKey() { - return ruleKey; - } + public String getRuleKey() { + return ruleKey; + } - public void setRuleKey(String ruleKey) { - this.ruleKey = ruleKey; - } + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } - public int getWaitTimeoutInSecond() { - return waitTimeoutInSecond; - } + public int getWaitTimeoutInSecond() { + return waitTimeoutInSecond; + } - public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { - this.waitTimeoutInSecond = waitTimeoutInSecond; - } + public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { + this.waitTimeoutInSecond = waitTimeoutInSecond; + } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java index ad132357..b8d01763 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java +++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/factorybean/ConsulDataSourceFactoryBean.java @@ -18,6 +18,7 @@ package com.alibaba.cloud.sentinel.datasource.factorybean; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.consul.ConsulDataSource; + import org.springframework.beans.factory.FactoryBean; /** @@ -28,68 +29,63 @@ import org.springframework.beans.factory.FactoryBean; */ public class ConsulDataSourceFactoryBean implements FactoryBean { - private String host; + private String host; - private int port; + private int port; - private String ruleKey; + private String ruleKey; - private int waitTimeoutInSecond; + private int waitTimeoutInSecond; - private Converter converter; + private Converter converter; - @Override - public ConsulDataSource getObject() throws Exception { - return new ConsulDataSource( - host, - port, - ruleKey, - waitTimeoutInSecond, - converter); - } + @Override + public ConsulDataSource getObject() throws Exception { + return new ConsulDataSource(host, port, ruleKey, waitTimeoutInSecond, converter); + } - @Override - public Class getObjectType() { - return ConsulDataSource.class; - } + @Override + public Class getObjectType() { + return ConsulDataSource.class; + } - public String getHost() { - return host; - } + public String getHost() { + return host; + } - public void setHost(String host) { - this.host = host; - } + public void setHost(String host) { + this.host = host; + } - public int getPort() { - return port; - } + public int getPort() { + return port; + } - public void setPort(int port) { - this.port = port; - } + public void setPort(int port) { + this.port = port; + } - public String getRuleKey() { - return ruleKey; - } + public String getRuleKey() { + return ruleKey; + } - public void setRuleKey(String ruleKey) { - this.ruleKey = ruleKey; - } + public void setRuleKey(String ruleKey) { + this.ruleKey = ruleKey; + } - public int getWaitTimeoutInSecond() { - return waitTimeoutInSecond; - } + public int getWaitTimeoutInSecond() { + return waitTimeoutInSecond; + } - public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { - this.waitTimeoutInSecond = waitTimeoutInSecond; - } + public void setWaitTimeoutInSecond(int waitTimeoutInSecond) { + this.waitTimeoutInSecond = waitTimeoutInSecond; + } - public Converter getConverter() { - return converter; - } + public Converter getConverter() { + return converter; + } - public void setConverter(Converter converter) { - this.converter = converter; - } + public void setConverter(Converter converter) { + this.converter = converter; + } } From 27ed9ff1c9d2dff1f94be6b82827ae28b45beff0 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 14 Apr 2020 13:36:57 +0800 Subject: [PATCH 3/5] Polish alibaba/spring-cloud-alibaba#1363 : Sync spring-cloud-starter-dubbo module --- .../registry/AbstractSpringCloudRegistry.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java index b4f656b2..ae511c28 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractSpringCloudRegistry.java @@ -98,10 +98,10 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { private final ConfigurableApplicationContext applicationContext; public AbstractSpringCloudRegistry(URL url, DiscoveryClient discoveryClient, - DubboServiceMetadataRepository dubboServiceMetadataRepository, - DubboMetadataServiceProxy dubboMetadataConfigServiceProxy, - JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory, - ConfigurableApplicationContext applicationContext) { + DubboServiceMetadataRepository dubboServiceMetadataRepository, + DubboMetadataServiceProxy dubboMetadataConfigServiceProxy, + JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory, + ConfigurableApplicationContext applicationContext) { super(url); this.servicesLookupInterval = url .getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L); @@ -190,7 +190,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { * @param listener {@link NotifyListener} */ private void registerServiceInstancesChangedEventListener(URL url, - NotifyListener listener) { + NotifyListener listener) { String listenerId = generateId(url); if (registerListeners.add(listenerId)) { applicationContext.addApplicationListener( @@ -217,8 +217,8 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { } protected void subscribeDubboServiceURL(URL url, NotifyListener listener, - String serviceName, - Function> serviceInstancesFunction) { + String serviceName, + Function> serviceInstancesFunction) { if (logger.isInfoEnabled()) { logger.info( @@ -355,7 +355,7 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry { } private List getExportedURLs(DubboMetadataService dubboMetadataService, - URL url) { + URL url) { String serviceInterface = url.getServiceInterface(); String group = url.getParameter(GROUP_KEY); String version = url.getParameter(VERSION_KEY); From 787b529f7c1b990374d95dee902f86f3571706fe Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 14 Apr 2020 13:37:49 +0800 Subject: [PATCH 4/5] Polish alibaba/spring-cloud-alibaba#1363 : Sync spring-cloud-starter-alibaba-seata module --- .../SeataHystrixConcurrencyStrategy.java | 97 ++++++++++++++++++- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java index 59253059..338d1c92 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/hystrix/SeataHystrixConcurrencyStrategy.java @@ -16,23 +16,104 @@ package com.alibaba.cloud.seata.feign.hystrix; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import com.netflix.hystrix.HystrixThreadPoolKey; +import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; +import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; +import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; +import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; +import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; +import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; +import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; +import com.netflix.hystrix.strategy.properties.HystrixProperty; import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; /** * @author xiaojing */ public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { + private final Logger logger = LoggerFactory + .getLogger(SeataHystrixConcurrencyStrategy.class); private HystrixConcurrencyStrategy delegate; public SeataHystrixConcurrencyStrategy() { - this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); - HystrixPlugins.reset(); - HystrixPlugins.getInstance().registerConcurrencyStrategy(this); + try { + this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); + if (this.delegate instanceof SeataHystrixConcurrencyStrategy) { + return; + } + HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins + .getInstance().getCommandExecutionHook(); + HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance() + .getEventNotifier(); + HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance() + .getMetricsPublisher(); + HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance() + .getPropertiesStrategy(); + logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, + propertiesStrategy); + HystrixPlugins.reset(); + HystrixPlugins.getInstance().registerConcurrencyStrategy(this); + HystrixPlugins.getInstance() + .registerCommandExecutionHook(commandExecutionHook); + HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); + HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); + HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); + } + catch (Exception ex) { + logger.error("Failed to register Seata Hystrix Concurrency Strategy", ex); + } + } + + private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier, + HystrixMetricsPublisher metricsPublisher, + HystrixPropertiesStrategy propertiesStrategy) { + if (logger.isDebugEnabled()) { + logger.debug("Current Hystrix plugins configuration is [" + + "concurrencyStrategy [" + this.delegate + "]," + "eventNotifier [" + + eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "]," + + "propertiesStrategy [" + propertiesStrategy + "]," + "]"); + logger.debug("Registering Seata Hystrix Concurrency Strategy."); + } + } + + @Override + public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, + HystrixProperty corePoolSize, + HystrixProperty maximumPoolSize, + HystrixProperty keepAliveTime, TimeUnit unit, + BlockingQueue workQueue) { + return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, + keepAliveTime, unit, workQueue); + } + + @Override + public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, + HystrixThreadPoolProperties threadPoolProperties) { + return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties); + } + + @Override + public BlockingQueue getBlockingQueue(int maxQueueSize) { + return this.delegate.getBlockingQueue(maxQueueSize); + } + + @Override + public HystrixRequestVariable getRequestVariable( + HystrixRequestVariableLifecycle rv) { + return this.delegate.getRequestVariable(rv); } @Override @@ -52,7 +133,8 @@ public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy return wrappedCallable; } - return new SeataContextCallable<>(wrappedCallable); + return new SeataContextCallable<>(wrappedCallable, + RequestContextHolder.getRequestAttributes()); } private static class SeataContextCallable implements Callable { @@ -61,19 +143,24 @@ public class SeataHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy private final String xid; - SeataContextCallable(Callable actual) { + private final RequestAttributes requestAttributes; + + SeataContextCallable(Callable actual, RequestAttributes requestAttribute) { this.actual = actual; + this.requestAttributes = requestAttribute; this.xid = RootContext.getXID(); } @Override public K call() throws Exception { try { + RequestContextHolder.setRequestAttributes(requestAttributes); RootContext.bind(xid); return actual.call(); } finally { RootContext.unbind(); + RequestContextHolder.resetRequestAttributes(); } } From 0da36b8b2e8d4604e429ebbbfed0b5886da2d2c6 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Tue, 14 Apr 2020 13:45:22 +0800 Subject: [PATCH 5/5] Polish alibaba/spring-cloud-alibaba#1363 : Sync spring-cloud-starter-dubbo module --- .../DubboServiceMetadataRepository.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java index 7c7a57cb..372604a0 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java @@ -190,7 +190,7 @@ public class DubboServiceMetadataRepository // // private static Map getMap(Map> repository, - String key) { + String key) { return getOrDefault(repository, key, newHashMap()); } @@ -343,7 +343,7 @@ public class DubboServiceMetadataRepository } private void addDubboMetadataServiceURLsMetadata(Map metadata, - List dubboMetadataServiceURLs) { + List dubboMetadataServiceURLs) { String dubboMetadataServiceURLsJSON = jsonUtils.toJSON(dubboMetadataServiceURLs); metadata.put(DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME, dubboMetadataServiceURLsJSON); @@ -390,7 +390,7 @@ public class DubboServiceMetadataRepository } public List findSubscribedDubboMetadataServiceURLs(String serviceName, - String group, String version, String protocol) { + String group, String version, String protocol) { String serviceKey = URL.buildKey(serviceName, group, version); List urls = null; @@ -403,9 +403,11 @@ public class DubboServiceMetadataRepository return emptyList(); } - return hasText(protocol) ? urls.stream() - .filter(url -> url.getProtocol().equalsIgnoreCase(protocol)) - .collect(Collectors.toList()) : unmodifiableList(urls); + return hasText(protocol) + ? urls.stream() + .filter(url -> url.getProtocol().equalsIgnoreCase(protocol)) + .collect(Collectors.toList()) + : unmodifiableList(urls); } /** @@ -470,7 +472,7 @@ public class DubboServiceMetadataRepository } public Integer getDubboProtocolPort(ServiceInstance serviceInstance, - String protocol) { + String protocol) { String protocolProperty = getDubboProtocolPropertyName(protocol); Map metadata = serviceInstance.getMetadata(); String protocolPort = metadata.get(protocolProperty); @@ -478,7 +480,7 @@ public class DubboServiceMetadataRepository } public List getExportedURLs(String serviceInterface, String group, - String version) { + String version) { String serviceKey = URL.buildKey(serviceInterface, group, version); return allExportedURLs.getOrDefault(serviceKey, Collections.emptyList()); } @@ -535,7 +537,7 @@ public class DubboServiceMetadataRepository * @return {@link DubboRestServiceMetadata} if matched, or null */ public DubboRestServiceMetadata get(String serviceName, - RequestMetadata requestMetadata) { + RequestMetadata requestMetadata) { return match(dubboRestServiceMetadataRepository, serviceName, requestMetadata); } @@ -552,7 +554,7 @@ public class DubboServiceMetadataRepository } private T match(Map> repository, - String serviceName, RequestMetadata requestMetadata) { + String serviceName, RequestMetadata requestMetadata) { Map map = repository.get(serviceName);