From 3f55794dd2fbc08ba2886d106962229ebcb607db Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Fri, 31 Jan 2020 00:44:08 +0800 Subject: [PATCH] =?UTF-8?q?sentinel=20=E4=BD=BF=E7=94=A8=20nacos=20?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E6=95=B0=E6=8D=AE=E6=BA=90=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab-46/lab-46-sentinel-demo-nacos/pom.xml | 25 ++++---- .../config/SentinelConfiguration.java | 28 ++++++--- .../config/SpringMvcConfiguration.java | 16 ++++- .../controller/DemoController.java | 61 +++++++++++++++++++ .../src/main/resources/application.yaml | 11 ---- .../controller/DemoController.java | 23 +++++++ 6 files changed, 133 insertions(+), 31 deletions(-) delete mode 100644 lab-46/lab-46-sentinel-demo-nacos/src/main/resources/application.yaml 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(); + } + }