mirror of
https://gitee.com/yudaocode/SpringBoot-Labs.git
synced 2026-09-03 13:57:29 +08:00
增加 spring cloud alibaba sentinel 服务容错
This commit is contained in:
66
labx-04/labx-04-sca-sentinel-file-provider/pom.xml
Normal file
66
labx-04/labx-04-sca-sentinel-file-provider/pom.xml
Normal 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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 # 规则类型
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user