mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
import changes from master
reorganizing modules
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>com.alibaba.csp</groupId>-->
|
||||
|
||||
@@ -184,7 +184,7 @@ Spring Boot 应用支持通过 Endpoint 来暴露相关信息,Sentinel Starter
|
||||
* Spring Boot 1.x 中添加配置 `management.security.enabled=false`
|
||||
* Spring Boot 2.x 中添加配置 `management.endpoints.web.exposure.include=*`
|
||||
|
||||
Spring Boot 1.x 可以通过访问 http://127.0.0.1:18083/sentinel 来查看 Sentinel Endpoint 的信息。Spring Boot 2.x 可以通过访问 http://127.0.0.1:18083/acutator/sentinel 来访问。
|
||||
Spring Boot 1.x 可以通过访问 http://127.0.0.1:18083/sentinel 来查看 Sentinel Endpoint 的信息。Spring Boot 2.x 可以通过访问 http://127.0.0.1:18083/actuator/sentinel 来访问。
|
||||
|
||||
<p align="center"><img src="https://cdn.yuque.com/lark/0/2018/png/54319/1532084199224-1a41591d-7a06-4680-be8a-5de319ac635d.png" width="480" heigh='360' ></p>
|
||||
|
||||
|
||||
@@ -193,15 +193,27 @@ Now ReadableDataSource type support 5 categories: `file`, `nacos`, `zk`, `apollo
|
||||
|
||||
If you want to use `nacos`, `zk`, `apollo` or `redis` ReadableDataSource, you could add `sentinel-datasource-nacos`, `sentinel-datasource-zookeeper`,`sentinel-datasource-apollo` or `sentinel-datasource-redis` dependency.
|
||||
|
||||
|
||||
|
||||
When ReadableDataSource load rule data successfully, console will print some logs:
|
||||
|
||||
```
|
||||
[Sentinel Starter] DataSource ds1-sentinel-file-datasource load 3 DegradeRule
|
||||
[Sentinel Starter] DataSource ds2-sentinel-nacos-datasource load 2 FlowRule
|
||||
```
|
||||
## Warning
|
||||
You should use `file` ReadableDataSource in a fatjar carefully or you may get error like this below
|
||||
|
||||
```
|
||||
java.lang.RuntimeException: [Sentinel Starter] DataSource ds1 handle file [classpath: flowrule.json] error: class path resource [flowrule.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:xxx/xxx.jar!/BOOT-INF/classes!/flowrule.jso
|
||||
```
|
||||
|
||||
You could use absolute path when you use File datasource & fat jar.
|
||||
It is recommended to use Nacos/Apollo/Zookeeper/Redis datasource to store rules.
|
||||
|
||||
https://github.com/alibaba/spring-cloud-alibaba/issues/428
|
||||
|
||||
## More
|
||||
For more information about Sentinel, see [Sentinel Project](https://github.com/alibaba/Sentinel).
|
||||
|
||||
If you have any ideas or suggestions for Spring Cloud Sentinel starter, please don't hesitate to tell us by submitting github issues.
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
|
||||
@@ -9,7 +25,11 @@ import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
/**
|
||||
* @author fangjian
|
||||
*/
|
||||
public class ExceptionUtil {
|
||||
public final class ExceptionUtil {
|
||||
|
||||
private ExceptionUtil() {
|
||||
|
||||
}
|
||||
|
||||
public static SentinelClientHttpResponse handleException(HttpRequest request,
|
||||
byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import java.util.List;
|
||||
@@ -11,9 +27,11 @@ import com.alibaba.fastjson.TypeReference;
|
||||
* @author fangjian
|
||||
*/
|
||||
public class JsonFlowRuleListConverter implements Converter<String, List<FlowRule>> {
|
||||
|
||||
@Override
|
||||
public List<FlowRule> convert(String source) {
|
||||
return JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,33 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelCircuitBreakerFactory;
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder;
|
||||
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -15,7 +38,8 @@ import org.springframework.web.client.RestTemplate;
|
||||
public class ServiceApplication {
|
||||
|
||||
@Bean
|
||||
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
|
||||
@SentinelRestTemplate(blockHandler = "handleException",
|
||||
blockHandlerClass = ExceptionUtil.class)
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
@@ -30,6 +54,18 @@ public class ServiceApplication {
|
||||
return new JsonFlowRuleListConverter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<SentinelCircuitBreakerFactory> defaultConfig() {
|
||||
return factory -> {
|
||||
factory.configureDefault(
|
||||
id -> new SentinelConfigBuilder().resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_RT).setCount(100)
|
||||
.setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ServiceApplication.class, args);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -17,26 +33,42 @@ public class TestController {
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@RequestMapping(value = "/hello", method = RequestMethod.GET)
|
||||
@Autowired
|
||||
private CircuitBreakerFactory circuitBreakerFactory;
|
||||
|
||||
@GetMapping("/hello")
|
||||
@SentinelResource("resource")
|
||||
public String hello() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/aa", method = RequestMethod.GET)
|
||||
@GetMapping("/aa")
|
||||
@SentinelResource("aa")
|
||||
public String aa(int b, int a) {
|
||||
return "Hello test";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/test", method = RequestMethod.GET)
|
||||
@GetMapping("/test")
|
||||
public String test1() {
|
||||
return "Hello test";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/template", method = RequestMethod.GET)
|
||||
@GetMapping("/template")
|
||||
public String client() {
|
||||
return restTemplate.getForObject("http://www.taobao.com/test", String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/slow")
|
||||
public String slow() {
|
||||
return circuitBreakerFactory.create("slow").run(() -> {
|
||||
try {
|
||||
Thread.sleep(500L);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "slow";
|
||||
}, throwable -> "fallback");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @author yuhuangbin
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/errorPage").setViewName("errorPage");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,17 @@
|
||||
spring.application.name=sentinel-example
|
||||
server.port=18083
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
|
||||
# we can disable health check, default is enable
|
||||
management.health.diskspace.enabled=false
|
||||
# management.health.sentinel.enabled=false
|
||||
|
||||
spring.cloud.sentinel.transport.dashboard=localhost:8080
|
||||
spring.cloud.sentinel.eager=true
|
||||
|
||||
#spring.cloud.sentinel.block-page=/errorPage
|
||||
#spring.cloud.sentinel.filter.enabled=false
|
||||
#spring.cloud.sentinel.http-method-specify=false
|
||||
|
||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||
@@ -20,7 +29,4 @@ spring.cloud.sentinel.datasource.ds4.file.file=classpath: system.json
|
||||
spring.cloud.sentinel.datasource.ds4.file.rule-type=system
|
||||
|
||||
spring.cloud.sentinel.datasource.ds5.file.file=classpath: param-flow.json
|
||||
spring.cloud.sentinel.datasource.ds5.file.rule-type=param-flow
|
||||
|
||||
|
||||
management.endpoint.health.show-details=always
|
||||
spring.cloud.sentinel.datasource.ds5.file.rule-type=param_flow
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
This is error page.
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,7 +10,6 @@
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>sentinel-dubbo-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>api for sentinel dubbo example</description>
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
@@ -42,7 +48,6 @@
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
# Sentinel Feign Example
|
||||
|
||||
## 项目说明
|
||||
|
||||
本项目演示如何使用 Sentinel starter 完成 Spring Cloud 应用调用。
|
||||
|
||||
[Sentinel](https://github.com/alibaba/Sentinel) 是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
|
||||
|
||||
[OpenFeign](https://github.com/spring-cloud/spring-cloud-openfeign)是一款声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
|
||||
|
||||
本项目专注于Sentinel与Feign的整合,关于Sentinel的更多特性可以查看[sentinel-core-example](https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example)。
|
||||
|
||||
## 示例
|
||||
|
||||
### 服务消费方
|
||||
在启动示例进行演示之前,我们先了解一下 Feign 如何接入 Sentinel。
|
||||
**注意 本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
|
||||
|
||||
1. 首先,修改 pom.xml 文件,引入 Sentinel starter 和 Dubbo starter。
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
```
|
||||
2. 其次, 使用nacos 注册中心
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
3. 定义FeignClient,及其降级配置
|
||||
|
||||
- 定义FeignClient
|
||||
```java
|
||||
@FeignClient(name = "service-provider", fallbackFactory = EchoServiceFallbackFactory.class)
|
||||
public interface EchoService {
|
||||
|
||||
/**
|
||||
* 调用服务提供方的输出接口
|
||||
*
|
||||
* @param str 用户输入
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/echo/{str}")
|
||||
String echo(@PathVariable("str") String str);
|
||||
}
|
||||
```
|
||||
- 定义fallback 工厂,获取异常
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class EchoServiceFallbackFactory implements FallbackFactory<EchoServiceFallback> {
|
||||
@Override
|
||||
public EchoServiceFallback create(Throwable throwable) {
|
||||
return new EchoServiceFallback(throwable);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- 定义具体的fallback 实现
|
||||
```java
|
||||
public class EchoServiceFallback implements EchoService {
|
||||
private Throwable throwable;
|
||||
|
||||
EchoServiceFallback(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String echo(String str) {
|
||||
return "consumer-fallback-default-str" + throwable.getMessage();
|
||||
}
|
||||
}
|
||||
```
|
||||
### 服务提供方
|
||||
|
||||
1. 首先, 依赖nacos 注册中心
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
2. 定义服务提供方接口
|
||||
|
||||
```java
|
||||
@RestController
|
||||
public class EchoController {
|
||||
|
||||
@GetMapping("/echo/{str}")
|
||||
public String echo(@PathVariable String str) {
|
||||
return "provider-" + str;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
### 应用启动
|
||||
|
||||
|
||||
支持 IDE 直接启动和编译打包后启动。
|
||||
|
||||
- 启动nacos 注册中心
|
||||
|
||||
- 启动服务提供方:
|
||||
|
||||
1. IDE直接启动:找到主类 `ProviderApplication`,执行 main 方法启动应用。
|
||||
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar sentinel-feign-provider-example.jar`启动应用。
|
||||
|
||||
- 启动服务消费方:
|
||||
|
||||
1. IDE直接启动:找到主类 `ConsumerApplication`,执行 main 方法启动应用。
|
||||
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar sentinel-feign-consumer-example.jar`启动应用。
|
||||
@@ -0,0 +1,126 @@
|
||||
# Sentinel Feign Example
|
||||
|
||||
Project description
|
||||
|
||||
This project demonstrates how to use Sentinel starter to complete the Spring Cloud application call.
|
||||
|
||||
[Sentinel](https://github.com/alibaba/Sentinel) is alibaba open source distributed system flow defense components, Sentinel flow as the breakthrough point, from the flow control, fusing the drop, the stability of the system load multiple dimensions, such as protection services.
|
||||
|
||||
[OpenFeign](https://github.com/spring-cloud/spring-cloud-openfeign) is a declarative, templated HTTP client, Feign can help us faster and gracefully HTTP API calls.
|
||||
|
||||
By focusing on this project, the integration of Sentinel and Feign more characteristics about Sentinel can view [Sentinel - core - example](https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example).
|
||||
|
||||
## sample
|
||||
|
||||
Service consumer
|
||||
Before launching the example, let's see how Feign can access Sentinel.
|
||||
** note that this section is for your convenience only. The access has been completed in this sample code and you do not need to modify it. * *
|
||||
|
||||
First, modify the pom.xml file to introduce Sentinel starter and Dubbo starter.
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
```
|
||||
2. Secondly, nacos registries are used
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
3. Define the FeignClient and its degraded configuration
|
||||
|
||||
```java
|
||||
@FeignClient(name = "service-provider", fallbackFactory = EchoServiceFallbackFactory.class)
|
||||
public interface EchoService {
|
||||
|
||||
/**
|
||||
* 调用服务提供方的输出接口
|
||||
*
|
||||
* @param str 用户输入
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/echo/{str}")
|
||||
String echo(@PathVariable("str") String str);
|
||||
}
|
||||
```
|
||||
- define a fallback factory to get an exception
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class EchoServiceFallbackFactory implements FallbackFactory<EchoServiceFallback> {
|
||||
@Override
|
||||
public EchoServiceFallback create(Throwable throwable) {
|
||||
return new EchoServiceFallback(throwable);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- define a specific fallback implementation
|
||||
```java
|
||||
public class EchoServiceFallback implements EchoService {
|
||||
private Throwable throwable;
|
||||
|
||||
EchoServiceFallback(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String echo(String str) {
|
||||
return "consumer-fallback-default-str" + throwable.getMessage();
|
||||
}
|
||||
}
|
||||
```
|
||||
Service provider
|
||||
|
||||
1. First, rely on the nacos registry
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
2. Define the service provider interface
|
||||
|
||||
```java
|
||||
@RestController
|
||||
public class EchoController {
|
||||
|
||||
@GetMapping("/echo/{str}")
|
||||
public String echo(@PathVariable String str) {
|
||||
return "provider-" + str;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Application launch
|
||||
|
||||
|
||||
Support for IDE startup directly and after compilation and packaging.
|
||||
|
||||
- launch the nacos registry
|
||||
|
||||
- starting service provider:
|
||||
|
||||
1. IDE starts directly: find the main class `ProviderApplication` and execute the main method to start the application.
|
||||
2. Start after packaging and compilation: first execute `mvn clean package` to compile and package the project, and then execute `java-jar sentinel-feign-provider-example.jar` to start the application.
|
||||
|
||||
- starting service consumer:
|
||||
|
||||
1. IDE launch directly: find the main class `ConsumerApplication` and execute the main method to launch the application.
|
||||
2. Start after packaging and compilation: first execute `mvn clean package` to compile and package the project, and then execute `java-jar sentinel-feign-consumer-example.jar` to start the application.
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>sentinel-feign-consumer-example</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Example demonstrating how to use sentinel with feign</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>${maven-deploy-plugin.version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
@EnableFeignClients
|
||||
@SpringCloudApplication
|
||||
public class ConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ConsumerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.examples.controller;
|
||||
|
||||
import com.alibaba.cloud.examples.service.EchoService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
@RestController
|
||||
public class TestController {
|
||||
|
||||
@Autowired
|
||||
private EchoService echoService;
|
||||
|
||||
@GetMapping("/echo-feign/{str}")
|
||||
public String feign(@PathVariable String str) {
|
||||
return echoService.echo(str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.examples.fallback;
|
||||
|
||||
import com.alibaba.cloud.examples.service.EchoService;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-08-01
|
||||
* <p>
|
||||
* sentinel 降级处理
|
||||
*/
|
||||
public class EchoServiceFallback implements EchoService {
|
||||
|
||||
private Throwable throwable;
|
||||
|
||||
EchoServiceFallback(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用服务提供方的输出接口.
|
||||
* @param str 用户输入
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String echo(String str) {
|
||||
return "consumer-fallback-default-str" + throwable.getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.examples.fallback;
|
||||
|
||||
import feign.hystrix.FallbackFactory;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-08-01
|
||||
*/
|
||||
@Component
|
||||
public class EchoServiceFallbackFactory implements FallbackFactory<EchoServiceFallback> {
|
||||
|
||||
@Override
|
||||
public EchoServiceFallback create(Throwable throwable) {
|
||||
return new EchoServiceFallback(throwable);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.examples.service;
|
||||
|
||||
import com.alibaba.cloud.examples.fallback.EchoServiceFallbackFactory;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-08-01
|
||||
* <p>
|
||||
* example feign client
|
||||
*/
|
||||
@FeignClient(name = "service-provider",
|
||||
fallbackFactory = EchoServiceFallbackFactory.class)
|
||||
public interface EchoService {
|
||||
|
||||
/**
|
||||
* 调用服务提供方的输出接口.
|
||||
* @param str 用户输入
|
||||
* @return echo result
|
||||
*/
|
||||
@GetMapping("/echo/{str}")
|
||||
String echo(@PathVariable("str") String str);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
server:
|
||||
port: 18087
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: service-consumer
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
feign:
|
||||
sentinel:
|
||||
enabled: true
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>sentinel-feign-provider-example</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Example demonstrating how to use sentinel with feign</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>${maven-deploy-plugin.version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.examples;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ProviderApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.examples.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2019-08-01
|
||||
*/
|
||||
@RestController
|
||||
public class EchoController {
|
||||
|
||||
@GetMapping("/echo/{str}")
|
||||
public String echo(@PathVariable String str) {
|
||||
return "provider-" + str;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
server:
|
||||
port: 18088
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: service-provider
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: '*'
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -40,8 +39,7 @@ public class MySCGConfiguration {
|
||||
@Override
|
||||
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange,
|
||||
Throwable t) {
|
||||
return ServerResponse.status(444)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
return ServerResponse.status(444).contentType(MediaType.APPLICATION_JSON)
|
||||
.body(fromObject("SCS Sentinel block"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -25,7 +25,6 @@ import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -31,15 +31,13 @@ spring:
|
||||
ruleType: gw-api-group
|
||||
transport:
|
||||
dashboard: localhost:8080
|
||||
# filter:
|
||||
# enabled: true
|
||||
filter:
|
||||
enabled: true
|
||||
scg.fallback:
|
||||
mode: redirect
|
||||
redirect: http://www.taobao.com
|
||||
mode: response
|
||||
response-status: 444
|
||||
response-body: 1234
|
||||
scg:
|
||||
order: -100
|
||||
# response-status: 444
|
||||
# response-body: 1234
|
||||
# content-type: text/plain
|
||||
|
||||
management.endpoints.web.exposure.include: "*"
|
||||
@@ -19,4 +19,4 @@
|
||||
"fieldName": "name"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,10 +16,16 @@
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.ReactiveSentinelCircuitBreakerFactory;
|
||||
import com.alibaba.cloud.circuitbreaker.sentinel.SentinelConfigBuilder;
|
||||
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.Customizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -42,10 +48,28 @@ public class MyConfiguration {
|
||||
public Mono<ServerResponse> handleRequest(ServerWebExchange exchange,
|
||||
Throwable t) {
|
||||
return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.body(fromObject("block"));
|
||||
.contentType(MediaType.APPLICATION_JSON).body(fromObject("block"));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Customizer<ReactiveSentinelCircuitBreakerFactory> slowCustomizer() {
|
||||
return factory -> {
|
||||
factory.configure(builder -> builder.rules(Collections.singletonList(
|
||||
new DegradeRule("slow_mono").setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setCount(100).setTimeWindow(5))),
|
||||
"slow_mono");
|
||||
factory.configure(builder -> builder.rules(Collections.singletonList(
|
||||
new DegradeRule("slow_flux").setGrade(RuleConstant.DEGRADE_GRADE_RT)
|
||||
.setCount(100).setTimeWindow(5))),
|
||||
"slow_flux");
|
||||
factory.configureDefault(id -> new SentinelConfigBuilder().resourceName(id)
|
||||
.rules(Collections.singletonList(new DegradeRule(id)
|
||||
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)
|
||||
.setCount(0.5).setTimeWindow(10)))
|
||||
.build());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,13 +17,14 @@
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.reactor.SentinelReactorTransformer;
|
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||
@@ -31,6 +32,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
public class SentinelWebFluxController {
|
||||
|
||||
@Autowired
|
||||
private ReactiveCircuitBreakerFactory circuitBreakerFactory;
|
||||
|
||||
@GetMapping("/mono")
|
||||
public Mono<String> mono() {
|
||||
return Mono.just("simple string")
|
||||
@@ -38,6 +42,13 @@ public class SentinelWebFluxController {
|
||||
.transform(new SentinelReactorTransformer<>("mono"));
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
public Mono<String> test() {
|
||||
return Mono.just("simple string")
|
||||
// transform the publisher here.
|
||||
.transform(new SentinelReactorTransformer<>("test"));
|
||||
}
|
||||
|
||||
@GetMapping("/flux")
|
||||
public Flux<String> flux() {
|
||||
return Flux.fromArray(new String[] { "a", "b", "c" })
|
||||
@@ -45,19 +56,26 @@ public class SentinelWebFluxController {
|
||||
.transform(new SentinelReactorTransformer<>("flux"));
|
||||
}
|
||||
|
||||
@GetMapping("/aaa")
|
||||
@SentinelResource("abc")
|
||||
public Flux<String> aaa() {
|
||||
return Flux.fromArray(new String[] { "a", "b", "c" })
|
||||
// transform the publisher here.
|
||||
.transform(new SentinelReactorTransformer<>("aaa"));
|
||||
@GetMapping("/cbSlow")
|
||||
public Mono<String> cbSlow() {
|
||||
int delaySecs = 2;
|
||||
return WebClient.builder().baseUrl("http://httpbin.org/").build().get()
|
||||
.uri("/delay/" + delaySecs).retrieve().bodyToMono(String.class)
|
||||
.transform(it -> circuitBreakerFactory.create("slow_mono").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
public Flux<String> test() {
|
||||
return Flux.fromArray(new String[] { "a", "b", "c" })
|
||||
// transform the publisher here.
|
||||
.transform(new SentinelReactorTransformer<>("test"));
|
||||
@GetMapping("/cbError")
|
||||
public Mono<String> cbError() {
|
||||
String code = "500";
|
||||
return WebClient.builder().baseUrl("http://httpbin.org/").build().get()
|
||||
.uri("/status/" + code).retrieve().bodyToMono(String.class)
|
||||
.transform(it -> circuitBreakerFactory.create("cbError").run(it, t -> {
|
||||
t.printStackTrace();
|
||||
return Mono.just("fallback");
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ server.port=18084
|
||||
management.endpoints.web.exposure.include=*
|
||||
spring.cloud.sentinel.transport.dashboard=localhost:8080
|
||||
spring.cloud.sentinel.eager=true
|
||||
|
||||
|
||||
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
|
||||
spring.cloud.sentinel.datasource.ds1.file.data-type=json
|
||||
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
|
||||
|
||||
@@ -15,13 +15,4 @@
|
||||
"limitApp": "default",
|
||||
"strategy": 0
|
||||
}
|
||||
,
|
||||
{
|
||||
"resource": "abc",
|
||||
"controlBehavior": 0,
|
||||
"count": 0,
|
||||
"grade": 1,
|
||||
"limitApp": "default",
|
||||
"strategy": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
<!--<groupId>com.fasterxml.jackson.dataformat</groupId>-->
|
||||
<!--<artifactId>jackson-dataformat-xml</artifactId>-->
|
||||
<!--</dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 the original author or authors.
|
||||
* 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.
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -13,8 +13,8 @@ spring:
|
||||
ruleType: gw-api-group
|
||||
transport:
|
||||
dashboard: localhost:8080
|
||||
# filter:
|
||||
# enabled: true
|
||||
filter:
|
||||
enabled: false
|
||||
|
||||
management.endpoints.web.exposure.include: "*"
|
||||
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
"fieldName": "name"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user