增加 spring cloud alibaba sentinel 服务容错

This commit is contained in:
YunaiV
2020-02-15 11:56:53 +08:00
parent 96dae56eeb
commit bb2c23e681
8 changed files with 248 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>labx-04</artifactId>
<groupId>cn.iocoder.springboot.labs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>labx-04-sca-sentinel-file-provider</artifactId>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
</properties>
<!--
引入 Spring Boot、Spring Cloud、Spring Cloud Alibaba 三者 BOM 文件,进行依赖版本的管理,防止不兼容。
在 https://dwz.cn/mcLIfNKt 文章中Spring Cloud Alibaba 开发团队推荐了三者的依赖关系
-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入 Spring Cloud Alibaba Sentinel 相关依赖,使用 Sentinel 提供服务保障,并实现对其的自动配置 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProviderApplication.class, args);
}
}

View File

@@ -0,0 +1,84 @@
package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/demo")
public class DemoController {
// 测试【流量控制】
@GetMapping("/echo")
public String echo() {
return "echo";
}
@GetMapping("/test")
public String test() {
return "test";
}
// 测试【熔断降级】
@GetMapping("/sleep")
public String sleep() throws InterruptedException {
Thread.sleep(100L);
return "sleep";
}
// 测试【热点参数限流】
@GetMapping("/product_info")
@SentinelResource("demo_product_info_hot")
public String productInfo(Integer id) {
return "商品编号:" + id;
}
// 测试「Sentinel 客户端 API」
@GetMapping("/entry_demo")
public String entryDemo() {
Entry entry = null;
try {
// <1> 访问资源
entry = SphU.entry("entry_demo");
// <2> ... 执行业务逻辑
return "执行成功";
} catch (BlockException ex) { // <3>
return "被拒绝";
} finally {
// <4> 释放资源
if (entry != null) {
entry.exit();
}
}
}
// 测试「Sentinel @SentinelResource 注解」
@GetMapping("/annotations_demo")
@SentinelResource(value = "annotations_demo_resource",
blockHandler = "blockHandler",
fallback = "fallback")
public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException {
if (id == null) {
throw new IllegalArgumentException("id 参数不允许为空");
}
return "success...";
}
// BlockHandler 处理函数,参数最后多一个 BlockException其余与原函数一致.
public String blockHandler(Integer id, BlockException ex) {
return "block" + ex.getClass().getSimpleName();
}
// Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
public String fallback(Integer id, Throwable throwable) {
return "fallback" + throwable.getMessage();
}
}

View File

@@ -0,0 +1,18 @@
package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
throw e;
}
}

View File

@@ -0,0 +1,23 @@
package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
@Component
public class CustomRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
// <X> 从 Header 中,获得请求来源
String origin = request.getHeader("s-user");
// <Y> 如果为空,给一个默认的
if (StringUtils.isEmpty(origin)) {
origin = "default";
}
return origin;
}
}

View File

@@ -0,0 +1,21 @@
package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@Component
@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider")
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject实际项目最终定义一个 CommonResult。
public JSONObject blockExceptionHandler(BlockException blockException) {
return new JSONObject().fluentPut("code", 1024)
.fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName());
}
}

View File

@@ -0,0 +1,22 @@
spring:
application:
name: demo-provider
cloud:
# Sentinel 配置项,对应 SentinelProperties 配置属性类
sentinel:
enabled: true # 是否开启。默认为 true 开启
eager: true # 是否饥饿加载。默认为 false 关闭
transport:
dashboard: 127.0.0.1:7070 # Sentinel 控制台地址
filter:
url-patterns: /** # 拦截请求的地址。默认为 /*
# Sentinel 规则的数据源,是一个 Map 类型。key 为数据源名可自定义value 为数据源的具体配置
datasource:
ds1:
# 对应 DataSourcePropertiesConfiguration 类
file:
file: /Users/yunai/Sentinel/demo-provider/flow-rule.json # 配置规则所在文件。
recommendRefreshMs: 3000 # 定时读取实现刷新,默认为 3000 毫秒。
data-type: json # 数据格式
rule-type: FLOW # 规则类型

View File

@@ -15,6 +15,7 @@
<module>labx-04-sca-sentinel-demo01-provider</module>
<module>labx-04-sca-sentinel-nacos-provider</module>
<module>labx-04-sca-sentinel-apollo-provider</module>
<module>labx-04-sca-sentinel-file-provider</module>
</modules>