Pre Merge pull request !138 from koltZhang/master-jdk17

pull/138/MERGE
koltZhang 2025-05-04 08:01:10 +00:00 committed by Gitee
commit de58b782f9
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
30 changed files with 566 additions and 7 deletions

View File

@ -0,0 +1,11 @@
[
{
"resource": "feign-test", //
"count": 1000, // RT
"timeWindow": 5, //
"grade": 0, // 0: 1: 2:
"minRequestAmount": 2, //
"slowRatioThreshold": 0.2, //
"statIntervalMs": 10000 //
}
]

View File

@ -0,0 +1,12 @@
[
{
"resource": "feign-test", //
"resourceMode": 0, // API, 0: ROUTE ID, 1: API
"count": 1, // QPS线线
"grade": 1, // 0线1QPS
"controlBehavior": 2, // 02
"intervalSec": 10, //
"burst": 0, // burst
"maxQueueingTimeoutMs": 1000 //
}
]

View File

@ -0,0 +1,10 @@
[
{
"avgRt": 1, // RT
"highestCpuUsage": -1, // CPU 使
"highestSystemLoad": -1, // LOAD
"maxThread": -1, // 线
"qps": -1, // QPS
"count": 55 // CPU使
}
]

View File

@ -0,0 +1,7 @@
[
{
"resource": "sentinel_spring_web_context",
"limitApp": "/test",
"strategy": 0 // (01)
}
]

View File

@ -0,0 +1,11 @@
[
{
"resource": "/degrade-test",
"grade": 0, // 012
"count": 1000, // RTms/
"slowRatioThreshold": 0.1,// 1.8.0
"minRequestAmount": 10, //使
"timeWindow": 10, // s
"statIntervalMs": 1000 // ms 60*1000
}
]

View File

@ -0,0 +1,14 @@
[
{
"resource": "/flow-test", //
"limitApp": "default", // // default
"grade": 1, // (1:QPS; 0:线
"count": 1, //
"clusterMode": false, //
"controlBehavior": 0, // (0:; 1:Warm Up(); 2:)
"strategy": 0, // (0: 1:; 2:)
"warmUpPeriodSec": 10, //
"maxQueueingTimeMs": 500, //
"refResource": "rrr" // ()
}
]

View File

@ -0,0 +1,18 @@
[
{
"resource": "/param-flow-test",
"grade": 1, // QPS
"paramIdx": 0, //
"count": 13, //
"durationInSec": 6, //
"clusterMode": false, // false
"controlBehavior": 0, //
"limitApp": "default",
//
"paramFlowItemList": [{
"classType": "int", //
"count": 222, //
"object": "2" //
}]
}
]

View File

@ -0,0 +1,10 @@
[
{
"avgRt": 1, // RT
"highestCpuUsage": -1, // CPU 使
"highestSystemLoad": -1, // LOAD
"maxThread": -1, // 线
"qps": -1, // QPS
"count": 55 // CPU使
}
]

View File

@ -36,6 +36,16 @@
<optional>true</optional>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.framework.sentinel.config;
import cn.iocoder.yudao.framework.sentinel.core.handler.SentinelExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@Slf4j
public class YudaoSentinelAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SentinelExceptionHandler sentinelExceptionHandler() {
return new SentinelExceptionHandler();
}
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.framework.sentinel.core.handler;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
/**
* Sentinel
* @author koltZhang
*/
public class SentinelExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, String resourceName, BlockException e) throws Exception {
String msg = "未知异常";
int status = HttpStatus.TOO_MANY_REQUESTS.value();
if (e instanceof FlowException) {
msg = "请求限流";
} else if (e instanceof ParamFlowException) {
msg = "请求被热点参数限流";
} else if (e instanceof DegradeException) {
msg = "请求降级";
} else if (e instanceof AuthorityException) {
msg = "没有权限访问";
status = HttpStatus.UNAUTHORIZED.value();
} else if (e instanceof SystemBlockException) {
msg = "系统规则限流或降级";
}
ServletUtils.writeJSON(response, CommonResult.error(status, msg));
}
}

View File

@ -0,0 +1 @@
package cn.iocoder.yudao.framework.sentinel.core;

View File

@ -1,4 +1,5 @@
cn.iocoder.yudao.framework.idempotent.config.YudaoIdempotentConfiguration
cn.iocoder.yudao.framework.lock4j.config.YudaoLock4jConfiguration
cn.iocoder.yudao.framework.ratelimiter.config.YudaoRateLimiterConfiguration
cn.iocoder.yudao.framework.signature.config.YudaoApiSignatureAutoConfiguration
cn.iocoder.yudao.framework.signature.config.YudaoApiSignatureAutoConfiguration
cn.iocoder.yudao.framework.sentinel.config.YudaoSentinelAutoConfiguration

View File

@ -69,6 +69,24 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel Datasource Nacos -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
</dependencies>

View File

@ -13,6 +13,13 @@ spring:
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
# 日志文件配置
logging:
level:

View File

@ -250,4 +250,49 @@ knife4j:
yudao:
info:
version: 1.0.0
version: 1.0.0
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
enabled: true # 是否开启。默认为 true 开启
eager: true # 是否饥饿加载。默认为 false 关闭
filter:
url-patterns: /** # 拦截请求的地址。默认为 /*
#自定义流控降级异常信息
scg:
fallback:
mode: response
response-body: '{"code": 429, "msg":"服务压力过大,请稍后重试!"}'
# sentinel用nacos作为数据源的配置 (可导入/yudao-cloud/script/sentinel/system-server下对应规则使用时需去掉注释)
datasource:
# 流控规则
flow:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
data-id: ${spring.application.name}-gw-flow-rules # 在修改的sentinel 源码中定义的规则名
rule-type: gw_flow
# 降级规则
degrade:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-degrade-rules
rule-type: degrade
# 系统规则
system:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-system-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: system

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.infra.api.demo;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.api.demo.fallback.SentinelFeigenDemoFallback;
import cn.iocoder.yudao.module.infra.enums.ApiConstants;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* sentinel Feign demo
*/
@FeignClient(name = ApiConstants.NAME, fallback = SentinelFeigenDemoFallback.class)
public interface SentinelFeigenDemoApi {
String PREFIX = ApiConstants.PREFIX + "/provider/sentinel";
@GetMapping(PREFIX +"/test/{message}")
public CommonResult<String> providerSentinelTest(@PathVariable("message") String message);
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.infra.api.demo.fallback;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.api.demo.SentinelFeigenDemoApi;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Component
public class SentinelFeigenDemoFallback implements SentinelFeigenDemoApi {
@Override
public CommonResult<String> providerSentinelTest(String message) {
return CommonResult.error(HttpStatus.TOO_MANY_REQUESTS.value(), "对方服务不可用,开始服务降级处理");
}
}

View File

@ -147,6 +147,12 @@
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
</dependency>
<!-- 服务保障相关 TODO 芋艿:暂时去掉 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-protection</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.infra.api.demo;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* RESTful API Feign
*/
@RestController
@Validated
public class SentinelFeigenApiImpl implements SentinelFeigenDemoApi {
@Override
public CommonResult<String> providerSentinelTest(String message) {
return success("OK");
}
}

View File

@ -0,0 +1,68 @@
package cn.iocoder.yudao.module.infra.controller.admin.demo.sentinel;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* sentinel
* TODO
*/
@Tag(name = "管理后台 - sentinel")
@RestController
@RequestMapping("/infra/sentinel/demo")
@Validated
public class SentinelDemoController {
@GetMapping("flow")
@PermitAll
public String flow(String userName){
return "hello "+userName;
}
/**
*
*/
@GetMapping("flow-ref")
@PermitAll
public String flowRef(){
return "hello flowRef";
}
@GetMapping("degrade")
@PermitAll
public String degrade(String userName){
return "hello "+userName;
}
/**
*
* @param request
* @return
*/
@GetMapping("getOrderNo")
@SentinelResource(value = "getOrderNoResource",blockHandler = "getOrderNoBlockHandler",blockHandlerClass = SentinelDemoController.class)
@PermitAll
public String getOrderNo(HttpServletRequest request){
return UUID.randomUUID().toString();
}
/**
*
* @param e
* @return
*/
public static String getOrderNoBlockHandler(HttpServletRequest request, BlockException e){
return "不好意思,前方拥挤,请您稍后再试";
}
}

View File

@ -15,6 +15,13 @@ spring:
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项

View File

@ -15,6 +15,13 @@ spring:
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
--- #################### 数据库相关配置 ####################
spring:

View File

@ -91,6 +91,11 @@ easy-trans:
--- #################### RPC 远程调用相关配置 ####################
# 开启 feign 对 sentinel 的支持
feign:
sentinel:
enabled: true
--- #################### 消息队列相关 ####################
# rocketmq 配置项,对应 RocketMQProperties 配置类
@ -166,6 +171,7 @@ yudao:
enable: true
ignore-urls:
- /admin-api/infra/file/*/get/** # 获取图片,和租户无关
- /admin-api/infra/sentinel/demo/** # sentinel demo
ignore-tables:
- infra_codegen_column
- infra_codegen_table
@ -179,3 +185,61 @@ yudao:
- infra_data_source_config
debug: false
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
enabled: true # 是否开启。默认为 true 开启
eager: true # 是否饥饿加载。默认为 false 关闭
filter:
url-patterns: /** # 拦截请求的地址。默认为 /*
# sentinel用nacos作为数据源的配置 (可导入/yudao-cloud/script/sentinel/gateway-server下对应规则使用时需去掉注释)
datasource:
# 流控规则
flow:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
data-id: ${spring.application.name}-flow-rules # 在修改的sentinel 源码中定义的规则名
rule-type: flow
# 降级规则
degrade:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-degrade-rules
rule-type: degrade
# 授权规则
# authority:
# nacos:
# server-addr: ${spring.cloud.nacos.server-addr}
# namespace: ${spring.cloud.nacos.discovery.namespace}
# username: ${spring.cloud.nacos.username}
# password: ${spring.cloud.nacos.password}
# dataId: ${spring.application.name}-authority-rules
# rule-type: authority
# # 热点规则
# param-flow:
# nacos:
# server-addr: ${spring.cloud.nacos.server-addr}
# namespace: ${spring.cloud.nacos.discovery.namespace}
# username: ${spring.cloud.nacos.username}
# password: ${spring.cloud.nacos.password}
# dataId: ${spring.application.name}-param-flow-rules
# rule-type: param-flow
# # 系统规则
# system:
# nacos:
# server-addr: ${spring.cloud.nacos.server-addr}
# namespace: ${spring.cloud.nacos.discovery.namespace}
# username: ${spring.cloud.nacos.username}
# password: ${spring.cloud.nacos.password}
# dataId: ${spring.application.name}-system-rules
# groupId: DEFAULT_GROUP
# data-type: json
# rule-type: system

View File

@ -98,10 +98,10 @@
</dependency>
<!-- 服务保障相关 TODO 芋艿:暂时去掉 -->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.cloud</groupId>-->
<!-- <artifactId>yudao-spring-boot-starter-protection</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-protection</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.system.controller.admin.demo;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.api.demo.SentinelFeigenDemoApi;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "管理后台 - Sentinel Feigen Demo")
@RestController()
@RequestMapping("/system/sentinel/demo")
public class SentinelFeigenDemoController {
@Resource
private SentinelFeigenDemoApi sentinelFeigenDemoApiService;
@GetMapping("/provider/{message}")
@PermitAll
public CommonResult<String> providerSentinelTest(@PathVariable("message") String message) {
return sentinelFeigenDemoApiService.providerSentinelTest(message);
}
}

View File

@ -1,12 +1,16 @@
package cn.iocoder.yudao.module.system.framework.rpc.config;
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.infra.api.demo.SentinelFeigenDemoApi;
import cn.iocoder.yudao.module.infra.api.demo.fallback.SentinelFeigenDemoFallback;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {FileApi.class, WebSocketSenderApi.class, ConfigApi.class})
@EnableFeignClients(clients = {FileApi.class, WebSocketSenderApi.class, ConfigApi.class, SentinelFeigenDemoApi.class})
@Import({SentinelFeigenDemoFallback.class})
public class RpcConfiguration {
}

View File

@ -15,6 +15,14 @@ spring:
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项

View File

@ -15,6 +15,14 @@ spring:
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项

View File

@ -91,6 +91,11 @@ easy-trans:
--- #################### RPC 远程调用相关配置 ####################
# 开启 feign 对 sentinel 的支持
feign:
sentinel:
enabled: true
--- #################### 消息队列相关 ####################
# rocketmq 配置项,对应 RocketMQProperties 配置类
@ -175,6 +180,7 @@ yudao:
- /rpc-api/system/tenant/valid # 防止递归。避免调用 /rpc-api/system/tenant/valid 接口时,又去触发 /rpc-api/system/tenant/valid 去校验
- /rpc-api/system/tenant/id-list # 获得租户列表的时候,无需传递租户编号
- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递租户编号;主要解决上传文件的场景,前端不会传递 tenant-id
- /admin-api/system/sentinel/demo/provider/* # 示例演示,演示 Sentinel 熔断降级
ignore-tables:
- system_tenant
- system_tenant_package
@ -207,3 +213,62 @@ yudao:
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
debug: false
--- #################### Sentinel相关配置 ####################
spring:
cloud:
sentinel:
enabled: true # 是否开启。默认为 true 开启
eager: true # 是否饥饿加载。默认为 false 关闭
filter:
url-patterns: /** # 拦截请求的地址。默认为 /*
# sentinel用nacos作为数据源的配置 (可导入/yudao-cloud/script/sentinel/system-server下对应规则使用时需去掉注释)
datasource:
# 流控规则
flow:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
data-id: ${spring.application.name}-flow-rules # 在修改的sentinel 源码中定义的规则名
rule-type: flow
# 授权规则
authority:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-authority-rules
rule-type: authority
# 降级规则
degrade:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-degrade-rules
rule-type: degrade
# 热点规则
param-flow:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-param-flow-rules
rule-type: param-flow
# 系统规则
system:
nacos:
server-addr: ${spring.cloud.nacos.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
username: ${spring.cloud.nacos.username}
password: ${spring.cloud.nacos.password}
dataId: ${spring.application.name}-system-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: system