mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0e82361ff4
4
pom.xml
4
pom.xml
@ -45,8 +45,10 @@
|
|||||||
<email>flystar32@163.com</email>
|
<email>flystar32@163.com</email>
|
||||||
</developer>
|
</developer>
|
||||||
<developer>
|
<developer>
|
||||||
<name>fangjian</name>
|
<name>Jim Fang</name>
|
||||||
<email>fangjian0423@gmail.com</email>
|
<email>fangjian0423@gmail.com</email>
|
||||||
|
<organization>Alibaba</organization>
|
||||||
|
<url>https://github.com/fangjian0423</url>
|
||||||
</developer>
|
</developer>
|
||||||
<developer>
|
<developer>
|
||||||
<name>xiaolongzuo</name>
|
<name>xiaolongzuo</name>
|
||||||
|
@ -166,7 +166,7 @@ NOTE: 在使用 RocketMQ Binder 的同时也可以配置 rocketmq.** 用于触
|
|||||||
MessageBuilder builder = MessageBuilder.withPayload(msg)
|
MessageBuilder builder = MessageBuilder.withPayload(msg)
|
||||||
.setHeader(RocketMQHeaders.TAGS, "binder")
|
.setHeader(RocketMQHeaders.TAGS, "binder")
|
||||||
.setHeader(RocketMQHeaders.KEYS, "my-key")
|
.setHeader(RocketMQHeaders.KEYS, "my-key")
|
||||||
.setHeader("DELAY", "1");
|
.setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");
|
||||||
Message message = builder.build();
|
Message message = builder.build();
|
||||||
output().send(message);
|
output().send(message);
|
||||||
```
|
```
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
=== Circuit Breaker: Spring Cloud Circuit Breaker With Sentinel & Configuring Sentinel Circuit Breakers
|
||||||
|
|
||||||
|
==== Default Configuration
|
||||||
|
|
||||||
|
To provide a default configuration for all of your circuit breakers create a `Customizer` bean that is passed a
|
||||||
|
`SentinelCircuitBreakerFactory` or `ReactiveSentinelCircuitBreakerFactory`.
|
||||||
|
The `configureDefault` method can be used to provide a default configuration.
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public Customizer<SentinelCircuitBreakerFactory> defaultCustomizer() {
|
||||||
|
return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
You can choose to provide default circuit breaking rules via `SentinelConfigBuilder#rules(rules)`.
|
||||||
|
You can also choose to load circuit breaking rules later elsewhere using
|
||||||
|
`DegradeRuleManager.loadRules(rules)` API of Sentinel, or via Sentinel dashboard.
|
||||||
|
|
||||||
|
===== Reactive Example
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public Customizer<ReactiveSentinelCircuitBreakerFactory> defaultCustomizer() {
|
||||||
|
return factory -> factory.configureDefault(id -> new SentinelConfigBuilder(id)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
==== Specific Circuit Breaker Configuration
|
||||||
|
|
||||||
|
Similarly to providing a default configuration, you can create a `Customizer` bean this is passed a
|
||||||
|
`SentinelCircuitBreakerFactory`.
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public Customizer<SentinelCircuitBreakerFactory> slowCustomizer() {
|
||||||
|
String slowId = "slow";
|
||||||
|
List<DegradeRule> rules = Collections.singletonList(
|
||||||
|
new DegradeRule(slowId).setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||||
|
.setCount(100)
|
||||||
|
.setTimeWindow(10)
|
||||||
|
);
|
||||||
|
return factory -> factory.configure(builder -> builder.rules(rules), slowId);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
===== Reactive Example
|
||||||
|
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public Customizer<ReactiveSentinelCircuitBreakerFactory> customizer() {
|
||||||
|
List<DegradeRule> rules = Collections.singletonList(
|
||||||
|
new DegradeRule().setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||||
|
.setCount(100)
|
||||||
|
.setTimeWindow(10)
|
||||||
|
);
|
||||||
|
return factory -> factory.configure(builder -> builder.rules(rules), "foo", "bar");
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
@ -114,7 +114,7 @@ All the message types in this code are provided by the `spring-messaging`module.
|
|||||||
|
|
||||||
**The lower layer of Spring Cloud Stream also implements various code abstractions based on the previous code.**
|
**The lower layer of Spring Cloud Stream also implements various code abstractions based on the previous code.**
|
||||||
|
|
||||||
=== How to use Spring Cloud Alibaba RocketMQ Binder ###
|
=== How to use Spring Cloud Alibaba RocketMQ Binder
|
||||||
|
|
||||||
For using the Spring Cloud Alibaba RocketMQ Binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:
|
For using the Spring Cloud Alibaba RocketMQ Binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ For example, `TAGS`, `DELAY`, `TRANSACTIONAL_ARG`, `KEYS`, `WAIT_STORE_MSG_OK`,
|
|||||||
MessageBuilder builder = MessageBuilder.withPayload(msg)
|
MessageBuilder builder = MessageBuilder.withPayload(msg)
|
||||||
.setHeader(RocketMQHeaders.TAGS, "binder")
|
.setHeader(RocketMQHeaders.TAGS, "binder")
|
||||||
.setHeader(RocketMQHeaders.KEYS, "my-key")
|
.setHeader(RocketMQHeaders.KEYS, "my-key")
|
||||||
.setHeader("DELAY", "1");
|
.setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "1");
|
||||||
Message message = builder.build();
|
Message message = builder.build();
|
||||||
output().send(message);
|
output().send(message);
|
||||||
```
|
```
|
||||||
|
@ -255,7 +255,7 @@ To learn more about how dynamic data sources work in Sentinel, refer to https://
|
|||||||
|
|
||||||
=== Support Zuul
|
=== Support Zuul
|
||||||
|
|
||||||
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81[参考 Sentinel 网关限流]
|
Refer https://github.com/alibaba/Sentinel/wiki/API-Gateway-Flow-Control[API Gateway Flow Control]
|
||||||
|
|
||||||
If you want to use Sentinel Starter with Zuul, you need to add the `spring-cloud-alibaba-sentinel-gateway` dependency, and you need to add the `spring-cloud-starter-netflix-zuul` dependency to let Zuul AutoConfiguration class in the gateway module takes effect:
|
If you want to use Sentinel Starter with Zuul, you need to add the `spring-cloud-alibaba-sentinel-gateway` dependency, and you need to add the `spring-cloud-starter-netflix-zuul` dependency to let Zuul AutoConfiguration class in the gateway module takes effect:
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ If you want to use Sentinel Starter with Zuul, you need to add the `spring-cloud
|
|||||||
|
|
||||||
=== Support Spring Cloud Gateway
|
=== Support Spring Cloud Gateway
|
||||||
|
|
||||||
https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81[参考 Sentinel 网关限流]
|
Refer https://github.com/alibaba/Sentinel/wiki/API-Gateway-Flow-Control[API Gateway Flow Control]
|
||||||
|
|
||||||
If you want to use Sentinel Starter with Spring Cloud Gateway, you need to add the `spring-cloud-alibaba-sentinel-gateway` dependency and add the `spring-cloud-starter-gateway` dependency to let Spring Cloud Gateway AutoConfiguration class in the module takes effect:
|
If you want to use Sentinel Starter with Spring Cloud Gateway, you need to add the `spring-cloud-alibaba-sentinel-gateway` dependency and add the `spring-cloud-starter-gateway` dependency to let Spring Cloud Gateway AutoConfiguration class in the module takes effect:
|
||||||
|
|
||||||
@ -299,6 +299,8 @@ If you want to use Sentinel Starter with Spring Cloud Gateway, you need to add t
|
|||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
include::circuitbreaker-sentinel.adoc[]
|
||||||
|
|
||||||
=== Sentinel Endpoint
|
=== Sentinel Endpoint
|
||||||
|
|
||||||
Sentinel provides an Endpoint internally with a corresponding endpoint id of `sentinel`.
|
Sentinel provides an Endpoint internally with a corresponding endpoint id of `sentinel`.
|
||||||
|
@ -25,16 +25,19 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
|
||||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
|
import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
|
||||||
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
|
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
|
||||||
import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor;
|
import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.type.MethodMetadata;
|
import org.springframework.core.type.MethodMetadata;
|
||||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@ -56,8 +59,8 @@ import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
|
|||||||
@ConditionalOnClass(name = { "org.springframework.web.client.RestTemplate" })
|
@ConditionalOnClass(name = { "org.springframework.web.client.RestTemplate" })
|
||||||
@AutoConfigureAfter(name = {
|
@AutoConfigureAfter(name = {
|
||||||
"org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration" })
|
"org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration" })
|
||||||
public class DubboLoadBalancedRestTemplateAutoConfiguration
|
public class DubboLoadBalancedRestTemplateAutoConfiguration implements
|
||||||
implements BeanClassLoaderAware, SmartInitializingSingleton {
|
BeanClassLoaderAware, ApplicationContextAware, SmartInitializingSingleton {
|
||||||
|
|
||||||
private static final Class<DubboTransported> DUBBO_TRANSPORTED_CLASS = DubboTransported.class;
|
private static final Class<DubboTransported> DUBBO_TRANSPORTED_CLASS = DubboTransported.class;
|
||||||
|
|
||||||
@ -89,6 +92,9 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private Map<String, RestTemplate> restTemplates = Collections.emptyMap();
|
private Map<String, RestTemplate> restTemplates = Collections.emptyMap();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,8 +117,10 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration
|
|||||||
* {@link SmartInitializingSingleton} beans or
|
* {@link SmartInitializingSingleton} beans or
|
||||||
* {@link RestTemplateCustomizer#customize(RestTemplate) customization})
|
* {@link RestTemplateCustomizer#customize(RestTemplate) customization})
|
||||||
*/
|
*/
|
||||||
@EventListener(ApplicationStartedEvent.class)
|
@EventListener(ContextRefreshedEvent.class)
|
||||||
public void adaptRestTemplates() {
|
public void adaptRestTemplates(ContextRefreshedEvent event) {
|
||||||
|
|
||||||
|
if (event.getApplicationContext() == this.applicationContext) {
|
||||||
|
|
||||||
DubboTransportedAttributesResolver attributesResolver = new DubboTransportedAttributesResolver(
|
DubboTransportedAttributesResolver attributesResolver = new DubboTransportedAttributesResolver(
|
||||||
environment);
|
environment);
|
||||||
@ -126,6 +134,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the annotation attributes {@link RestTemplate} bean being annotated
|
* Gets the annotation attributes {@link RestTemplate} bean being annotated
|
||||||
@ -144,10 +153,10 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration
|
|||||||
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDefinition;
|
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDefinition;
|
||||||
MethodMetadata factoryMethodMetadata = annotatedBeanDefinition
|
MethodMetadata factoryMethodMetadata = annotatedBeanDefinition
|
||||||
.getFactoryMethodMetadata();
|
.getFactoryMethodMetadata();
|
||||||
attributes = factoryMethodMetadata != null
|
attributes = factoryMethodMetadata != null ? Optional
|
||||||
? Optional.ofNullable(factoryMethodMetadata
|
.ofNullable(factoryMethodMetadata
|
||||||
.getAnnotationAttributes(DUBBO_TRANSPORTED_CLASS_NAME)).orElse(attributes)
|
.getAnnotationAttributes(DUBBO_TRANSPORTED_CLASS_NAME))
|
||||||
: Collections.emptyMap();
|
.orElse(attributes) : Collections.emptyMap();
|
||||||
}
|
}
|
||||||
return attributesResolver.resolve(attributes);
|
return attributesResolver.resolve(attributes);
|
||||||
}
|
}
|
||||||
@ -188,4 +197,9 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration
|
|||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import org.apache.dubbo.config.annotation.Reference;
|
|||||||
*/
|
*/
|
||||||
public class FooServiceConsumer {
|
public class FooServiceConsumer {
|
||||||
|
|
||||||
@Reference(version = "${foo.service.version}", application = "${dubbo.application.id}", url = "dubbo://localhost:12345", timeout = 30000)
|
@Reference(version = "${foo.service.version}", application = "${dubbo.application.id}", url = "dubbo://localhost:12345?version=1.0.0", timeout = 30000)
|
||||||
private FooService fooService;
|
private FooService fooService;
|
||||||
|
|
||||||
public String hello(String name) {
|
public String hello(String name) {
|
||||||
|
@ -31,7 +31,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
|||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.type.MethodMetadata;
|
import org.springframework.core.type.MethodMetadata;
|
||||||
import org.springframework.core.type.StandardMethodMetadata;
|
import org.springframework.core.type.StandardMethodMetadata;
|
||||||
import org.springframework.core.type.classreading.MethodMetadataReadingVisitor;
|
|
||||||
import org.springframework.http.HttpRequest;
|
import org.springframework.http.HttpRequest;
|
||||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
@ -171,12 +170,6 @@ public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProces
|
|||||||
&& checkMethodMetadataReadingVisitor(beanDefinition);
|
&& checkMethodMetadataReadingVisitor(beanDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// private boolean checkStandardMethodMetadata(RootBeanDefinition beanDefinition) {
|
|
||||||
// return beanDefinition.getSource() instanceof StandardMethodMetadata
|
|
||||||
// && ((StandardMethodMetadata) beanDefinition.getSource())
|
|
||||||
// .isAnnotated(SentinelRestTemplate.class.getName());
|
|
||||||
// }
|
|
||||||
|
|
||||||
private boolean checkMethodMetadataReadingVisitor(RootBeanDefinition beanDefinition) {
|
private boolean checkMethodMetadataReadingVisitor(RootBeanDefinition beanDefinition) {
|
||||||
return beanDefinition.getSource() instanceof MethodMetadata
|
return beanDefinition.getSource() instanceof MethodMetadata
|
||||||
&& ((MethodMetadata) beanDefinition.getSource())
|
&& ((MethodMetadata) beanDefinition.getSource())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user