From 0427dcfa3d6cb106475b6160d5d22b8eb3f0b11b Mon Sep 17 00:00:00 2001
From: barney <15270405776@163.com>
Date: Mon, 8 May 2023 17:17:07 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Egateway=E8=B7=AF=E7=94=B1?=
=?UTF-8?q?=E5=92=8C=E5=88=86=E7=BB=84=E9=99=90=E6=B5=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 19 +++
gateway/pom.xml | 26 +++++
.../bnblogs/gateway/GatewayApplication.java | 3 +-
.../config/SentinelRouteConfiguration.java | 108 ++++++++++++++++++
gateway/src/main/resources/application.yml | 18 +--
provider/pom.xml | 6 +
.../provider/controller/IndexController.java | 20 ++++
7 files changed, 192 insertions(+), 8 deletions(-)
create mode 100644 gateway/src/main/java/cc/bnblogs/gateway/config/SentinelRouteConfiguration.java
diff --git a/README.md b/README.md
index 0103ff3..9ee9396 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,20 @@
### 基于SpringCloudAlibaba
+
+#### 版本关系
+
+| 依赖 | 版本号 |
+| :-------------------------------------: | :----------: |
+| `SpringBoot` | `2.6.11` |
+| `Spring Cloud` | ` 2021.0.4` |
+| `Spring Cloud Alibaba` | `2021.0.4.0` |
+| `Sentinel jar ` | `1.8.5` |
+| `Nacos jar ` | `2.0.4` |
+| `RocketMQ` | `4.9.4` |
+| `Seata` | `1.5.2` |
+| `spring-cloud-starter-loadbalancer` | `3.1.4` |
+| `spring-cloud-starter-gateway` | `3.1.4` |
+| `spring-cloud-starter-alibaba-sentinel` | `2021.0.4.0` |
+
+#### 详细文档
+
+地址:[https://hugo.bnblogs.cc/springcloud%E7%AC%94%E8%AE%B0/#%E5%9F%BA%E4%BA%8Enacos%E8%8E%B7%E5%8F%96%E5%85%B6%E4%BB%96%E6%9C%8D%E5%8A%A1](https://hugo.bnblogs.cc/springcloud%E7%AC%94%E8%AE%B0/#%E5%9F%BA%E4%BA%8Enacos%E8%8E%B7%E5%8F%96%E5%85%B6%E4%BB%96%E6%9C%8D%E5%8A%A1)
diff --git a/gateway/pom.xml b/gateway/pom.xml
index 04cd337..77357ba 100644
--- a/gateway/pom.xml
+++ b/gateway/pom.xml
@@ -20,6 +20,18 @@
spring-boot-starter
+
+ com.alibaba.csp
+ sentinel-spring-cloud-gateway-adapter
+ 1.8.6
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+ 2021.0.4.0
+
+
org.springframework.boot
spring-boot-starter-test
@@ -31,6 +43,20 @@
spring-cloud-starter-gateway
3.1.4
+
+ org.springframework
+ spring-webmvc
+
+
+ org.springframework
+ spring-webmvc
+
+
+ com.alibaba.csp
+ sentinel-api-gateway-adapter-common
+ 1.8.6
+ compile
+
diff --git a/gateway/src/main/java/cc/bnblogs/gateway/GatewayApplication.java b/gateway/src/main/java/cc/bnblogs/gateway/GatewayApplication.java
index b7a2579..98d6b3d 100644
--- a/gateway/src/main/java/cc/bnblogs/gateway/GatewayApplication.java
+++ b/gateway/src/main/java/cc/bnblogs/gateway/GatewayApplication.java
@@ -2,6 +2,8 @@ package cc.bnblogs.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.codec.ServerCodecConfigurer;
@SpringBootApplication
public class GatewayApplication {
@@ -9,5 +11,4 @@ public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
-
}
diff --git a/gateway/src/main/java/cc/bnblogs/gateway/config/SentinelRouteConfiguration.java b/gateway/src/main/java/cc/bnblogs/gateway/config/SentinelRouteConfiguration.java
new file mode 100644
index 0000000..a3df003
--- /dev/null
+++ b/gateway/src/main/java/cc/bnblogs/gateway/config/SentinelRouteConfiguration.java
@@ -0,0 +1,108 @@
+package cc.bnblogs.gateway.config;
+
+import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
+import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
+import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
+import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
+import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
+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.adapter.gateway.sc.SentinelGatewayFilter;
+import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
+import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
+import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.codec.ServerCodecConfigurer;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.server.ServerResponse;
+import org.springframework.web.reactive.result.view.ViewResolver;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.PostConstruct;
+import java.util.*;
+
+/**
+ * 限流规则
+ */
+@Configuration // 标记为配置类
+public class SentinelRouteConfiguration { // 添加分组api限流
+ private final List viewResolvers;
+ private final ServerCodecConfigurer serverCodecConfigurer;
+
+ public SentinelRouteConfiguration(ObjectProvider> viewResolversProvider, // 构造函数
+ ServerCodecConfigurer serverCodecConfigurer) {
+ this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
+ this.serverCodecConfigurer = serverCodecConfigurer;
+ }
+
+ @PostConstruct
+ public void initGatewayRules() {
+ //初始化限流规则
+ Set rules = new HashSet<>();
+ // 路由限流
+ GatewayFlowRule gatewayFlowRule = new GatewayFlowRule("provider_router");// 资源名称,对应routeId的值 此处限流用户服务
+ gatewayFlowRule.setCount(1); // 限流阀值
+ gatewayFlowRule.setIntervalSec(10); // 统计时间窗口(单位:秒),默认是1秒
+// rules.add(gatewayFlowRule); //为了测试分组限流,先把这个注释
+
+ // 定义两个api分组
+ // 加入分组限流
+ rules.add(new GatewayFlowRule("provider_api1").setCount(1).setIntervalSec(1));
+ rules.add(new GatewayFlowRule("provider_api2").setCount(1).setIntervalSec(1));
+
+ GatewayRuleManager.loadRules(rules); // 载入规则
+ }
+
+ //自定义API分组
+ @PostConstruct
+ private void initCustomizedApis() {
+ Set definitions = new HashSet<>();
+ ApiDefinition api1 = new ApiDefinition("provider_api1")
+ .setPredicateItems(new HashSet() {{
+ add(new ApiPathPredicateItem().setPattern("/provider/api1/**") // api1下所有接口均被限流
+ .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
+ }});
+ ApiDefinition api2 = new ApiDefinition("provider_api2")
+ .setPredicateItems(new HashSet() {{
+ add(new ApiPathPredicateItem().setPattern("/provider/api2/demo2")); // api2只对demo2接口限流
+ }});
+ definitions.add(api1);
+ definitions.add(api2);
+ GatewayApiDefinitionManager.loadApiDefinitions(definitions);
+ }
+
+ @PostConstruct
+ public void initBlockHandlers() { // 自定义限流后的界面
+ BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
+ @Override
+ public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
+ Map result = new HashMap<>(); // 限流提示
+ result.put("code", "0");
+ result.put("message", "您已被限流");
+ return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_UTF8).
+ body(BodyInserters.fromObject(result));
+ }
+ };
+ GatewayCallbackManager.setBlockHandler(blockRequestHandler);
+ }
+
+ @Bean
+ @Order(Ordered.HIGHEST_PRECEDENCE)
+ public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { // 配置限流异常处理器
+ return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
+ }
+
+ @Bean
+ @Order(Ordered.HIGHEST_PRECEDENCE)
+ public GlobalFilter sentinelGatewayFilter() { //初始化一个限流的过滤器
+ return new SentinelGatewayFilter();
+ }
+}
\ No newline at end of file
diff --git a/gateway/src/main/resources/application.yml b/gateway/src/main/resources/application.yml
index 6441ef8..a84ae72 100644
--- a/gateway/src/main/resources/application.yml
+++ b/gateway/src/main/resources/application.yml
@@ -8,10 +8,14 @@ spring:
discovery:
locator:
enabled: true
- routes:
- - id: provider_router
- uri: localhost:8080
- predicates:
- - Path=/provider/**
- filters:
- - StripPrefix=1
+ nacos:
+ discovery:
+ server-addr: localhost:8848
+ service: gateway
+# routes:
+# - id: provider_router
+# uri: http://localhost:8080
+# predicates:
+# - Path=/provider/**
+# filters:
+# - StripPrefix=1
diff --git a/provider/pom.xml b/provider/pom.xml
index 065b23f..0761d96 100644
--- a/provider/pom.xml
+++ b/provider/pom.xml
@@ -61,6 +61,12 @@
org.springframework.boot
spring-boot-starter-actuator
+
+ com.alibaba.csp
+ sentinel-spring-cloud-gateway-adapter
+ 1.8.6
+ compile
+
diff --git a/provider/src/main/java/cc/bnblogs/provider/controller/IndexController.java b/provider/src/main/java/cc/bnblogs/provider/controller/IndexController.java
index b8a4040..4c7d3dc 100644
--- a/provider/src/main/java/cc/bnblogs/provider/controller/IndexController.java
+++ b/provider/src/main/java/cc/bnblogs/provider/controller/IndexController.java
@@ -62,4 +62,24 @@ public class IndexController {
rocketMQTemplate.convertAndSend("orderTopic",order);
return order;
}
+
+ @GetMapping("/api1/demo1")
+ public String demo1(){
+ return "api1/demo1";
+ }
+
+ @GetMapping("/api1/demo2")
+ public String demo2(){
+ return "api1/demo2";
+ }
+
+ @GetMapping("/api2/demo1")
+ public String demo3(){
+ return "api2/demo1";
+ }
+
+ @GetMapping("/api2/demo2")
+ public String demo4(){
+ return "api2/demo2";
+ }
}