diff --git a/lab-46/lab-46-sentinel-demo-nacos/pom.xml b/lab-46/lab-46-sentinel-demo-nacos/pom.xml
index ea937479..1cc94441 100644
--- a/lab-46/lab-46-sentinel-demo-nacos/pom.xml
+++ b/lab-46/lab-46-sentinel-demo-nacos/pom.xml
@@ -13,19 +13,13 @@
lab-46-sentinel-demo-nacos
+
org.springframework.boot
spring-boot-starter-web
-
-
- com.alibaba.boot
- nacos-config-spring-boot-starter
- 0.2.4
-
-
com.alibaba.csp
@@ -44,11 +38,18 @@
sentinel-spring-webmvc-adapter
1.7.1
-
-
-
-
-
+
+
+ com.alibaba.csp
+ sentinel-parameter-flow-control
+ 1.7.1
+
+
+
+ com.alibaba.csp
+ sentinel-annotation-aspectj
+ 1.7.1
+
com.alibaba.csp
diff --git a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SentinelConfiguration.java b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SentinelConfiguration.java
index c849061c..f27aa17a 100644
--- a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SentinelConfiguration.java
+++ b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SentinelConfiguration.java
@@ -1,6 +1,6 @@
package cn.iocoder.springboot.lab46.sentineldemo.config;
-import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
+import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
@@ -19,13 +19,25 @@ import java.util.Properties;
public class SentinelConfiguration {
@Bean
- public NacosDataSource nacosDataSource(NacosConfigProperties nacosConfigProperties, ObjectMapper objectMapper) {
+ public SentinelResourceAspect sentinelResourceAspect() {
+ return new SentinelResourceAspect();
+ }
+
+ @Bean
+ public NacosDataSource nacosDataSource(ObjectMapper objectMapper) {
+ // Nacos 配置。这里先写死,推荐后面写到 application.yaml 配置文件中。
+ String serverAddress = "127.0.0.1:8848"; // Nacos 服务器地址
+ String namespace = ""; // Nacos 命名空间
+ String dataId = "demo-application-flow-rule"; // Nacos 配置集编号
+// String dataId = "example-sentinel"; // Nacos 配置集编号
+ String group = "DEFAULT_GROUP"; // Nacos 配置分组
+
+ // 创建 NacosDataSource 对象
Properties properties = new Properties();
- properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosConfigProperties.getServerAddr());
- properties.setProperty(PropertyKeyConst.NAMESPACE, nacosConfigProperties.getNamespace());
- NacosDataSource> nacosDataSource = new NacosDataSource<>(properties,
- nacosConfigProperties.getGroup(), nacosConfigProperties.getDataId(),
- new Converter>() {
+ properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverAddress);
+ properties.setProperty(PropertyKeyConst.NAMESPACE, namespace);
+ NacosDataSource> nacosDataSource = new NacosDataSource<>(properties, group, dataId,
+ new Converter>() { // 转换器,将读取的 Nacos 配置,转换成 FlowRule 数组
@Override
public List convert(String value) {
try {
@@ -35,6 +47,8 @@ public class SentinelConfiguration {
}
}
});
+
+ // 注册到 FlowRuleManager 中
FlowRuleManager.register2Property(nacosDataSource.getProperty());
return nacosDataSource;
}
diff --git a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SpringMvcConfiguration.java b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SpringMvcConfiguration.java
index 4fa703d1..c6d06427 100644
--- a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SpringMvcConfiguration.java
+++ b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/config/SpringMvcConfiguration.java
@@ -14,7 +14,7 @@ public class SpringMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Add Sentinel interceptor
- addSentinelWebTotalInterceptor(registry);
+// addSentinelWebTotalInterceptor(registry);
addSentinelWebInterceptor(registry);
}
@@ -23,6 +23,20 @@ public class SpringMvcConfiguration implements WebMvcConfigurer {
SentinelWebMvcConfig config = new SentinelWebMvcConfig();
config.setHttpMethodSpecify(true); // 是否包含请求方法。即基于 URL 创建的资源,是否包含 Method。
// config.setBlockExceptionHandler(new DefaultBlockExceptionHandler()); // 设置 BlockException 处理器。
+// config.setOriginParser(new RequestOriginParser() { // 设置请求来源解析器。用于黑白名单控制功能。
+//
+// @Override
+// public String parseOrigin(HttpServletRequest request) {
+// // 从 Header 中,获得请求来源
+// String origin = request.getHeader("s-user");
+// // 如果为空,给一个默认的
+// if (StringUtils.isEmpty(origin)) {
+// origin = "default";
+// }
+// return origin;
+// }
+//
+// });
// 添加 SentinelWebInterceptor 拦截器
registry.addInterceptor(new SentinelWebInterceptor(config)).addPathPatterns("/**");
diff --git a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
index 91b339ff..950b0916 100644
--- a/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
+++ b/lab-46/lab-46-sentinel-demo-nacos/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
@@ -1,7 +1,12 @@
package cn.iocoder.springboot.lab46.sentineldemo.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
@@ -18,4 +23,60 @@ public class DemoController {
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 {
+ // 访问资源
+ entry = SphU.entry("entry_demo");
+
+ // ... 执行业务逻辑
+
+ return "执行成功";
+ } catch (BlockException ex) {
+ return "被拒绝";
+ } finally {
+ // 释放资源
+ if (entry != null) {
+ entry.exit();
+ }
+ }
+ }
+
+ // 测试 @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();
+ }
+
}
diff --git a/lab-46/lab-46-sentinel-demo-nacos/src/main/resources/application.yaml b/lab-46/lab-46-sentinel-demo-nacos/src/main/resources/application.yaml
deleted file mode 100644
index f14b46a3..00000000
--- a/lab-46/lab-46-sentinel-demo-nacos/src/main/resources/application.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-nacos:
- # Nacos 配置中心的配置项,对应 NacosConfigProperties 配置类
- config:
- server-addr: 127.0.0.1:8848 # Nacos 服务器地址
- bootstrap:
- enable: true # 是否开启 Nacos 配置预加载功能。默认为 false。
- log-enable: true # 是否开启 Nacos 支持日志级别的加载时机。默认为 false。
- data-id: example-sentinel # 使用的 Nacos 配置集的 dataId。
- type: JSON # 使用的 Nacos 配置集的配置格式。默认为 PROPERTIES。
- group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP。
- namespace: # 使用的 Nacos 的命名空间,默认为 null。
diff --git a/lab-46/lab-46-sentinel-demo/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java b/lab-46/lab-46-sentinel-demo/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
index 4baee86a..950b0916 100644
--- a/lab-46/lab-46-sentinel-demo/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
+++ b/lab-46/lab-46-sentinel-demo/src/main/java/cn/iocoder/springboot/lab46/sentineldemo/controller/DemoController.java
@@ -6,6 +6,7 @@ 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
@@ -56,4 +57,26 @@ public class DemoController {
}
}
+ // 测试 @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();
+ }
+
}