mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-18 04:55:06 +08:00
1. 增加服务保障组件,支持限流、熔断等功能
2. 进一步完善文档
This commit is contained in:
@ -5,7 +5,6 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAdminServer // TODO 芋艿:需要迁移出去
|
||||
public class DashboardApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
@ -23,6 +23,8 @@ public interface GlobalErrorCodeConstants {
|
||||
ErrorCode FORBIDDEN = new ErrorCode(403, "没有该操作权限");
|
||||
ErrorCode NOT_FOUND = new ErrorCode(404, "请求未找到");
|
||||
ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
|
||||
ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
|
||||
ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
|
||||
|
||||
// ========== 服务端错误段 ==========
|
||||
|
||||
@ -30,7 +32,6 @@ public interface GlobalErrorCodeConstants {
|
||||
|
||||
// ========== 自定义错误段 ==========
|
||||
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
|
||||
ErrorCode CONCURRENCY_REQUESTS = new ErrorCode(901, "请求失败,请稍后重试"); // 并发请求,不允许
|
||||
|
||||
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Async-Job/?dashboard>
|
||||
<http://www.iocoder.cn/Spring-Boot/Async-Job/?yudao>
|
||||
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/dynamic-datasource/?yudao>
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao>
|
@ -14,7 +14,7 @@ public class DefaultLockFailureStrategy implements LockFailureStrategy {
|
||||
@Override
|
||||
public void onLockFailure(String key, long acquireTimeout, int acquireCount) {
|
||||
log.debug("[onLockFailure][线程:{} 获取锁失败,key:{} 获取超时时长:{} ms]", Thread.currentThread().getName(), key, acquireTimeout);
|
||||
throw new ServiceException(GlobalErrorCodeConstants.CONCURRENCY_REQUESTS);
|
||||
throw new ServiceException(GlobalErrorCodeConstants.LOCKED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
package cn.iocoder.dashboard.framework.monitor;
|
||||
|
||||
import de.codecentric.boot.admin.server.config.EnableAdminServer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableAdminServer
|
||||
public class AdminServerConfiguration {
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 使用 Spring Boot Admin 实现简单的监控平台
|
||||
*/
|
||||
package cn.iocoder.dashboard.framework.monitor;
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Admin/?yudao>
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao>
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Job/?yudao>
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 采用 Spring Data Redis 操作 Redis,底层使用 Redisson 作为客户端
|
||||
*/
|
||||
package cn.iocoder.dashboard.framework.redis;
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Redis/?yudao>
|
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* 使用 Resilience4j 组件,实现服务保障,包括:
|
||||
* 1. 熔断器
|
||||
* 2. 限流器
|
||||
* 3. 舱壁隔离
|
||||
* 4. 重试
|
||||
* 5. 限时器
|
||||
*/
|
||||
package cn.iocoder.dashboard.framework.resilience4j;
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Spring-Security/?github>
|
@ -1,2 +1,2 @@
|
||||
* 芋道 Spring Security 入门:<http://www.iocoder.cn/Spring-Boot/Spring-Security/?dashboard>
|
||||
* Spring Security 基本概念:<http://www.iocoder.cn/Fight/Spring-Security-4-1-0-Basic-concept-description/?dashboard>
|
||||
* 芋道 Spring Security 入门:<http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao>
|
||||
* Spring Security 基本概念:<http://www.iocoder.cn/Fight/Spring-Security-4-1-0-Basic-concept-description/?yudao>
|
||||
|
@ -1 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Swagger/?dashboard>
|
||||
<http://www.iocoder.cn/Spring-Boot/Swagger/?yudao>
|
||||
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao>
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 使用 Hibernate Validator 实现参数校验
|
||||
*/
|
||||
package cn.iocoder.dashboard.framework.validator;
|
@ -0,0 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/Validation/?yudao>
|
@ -4,6 +4,7 @@ import cn.iocoder.dashboard.common.exception.GlobalException;
|
||||
import cn.iocoder.dashboard.common.exception.ServiceException;
|
||||
import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||
import cn.iocoder.dashboard.framework.security.core.util.SecurityUtils;
|
||||
import io.github.resilience4j.ratelimiter.RequestNotPermitted;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.validation.BindException;
|
||||
@ -63,6 +64,9 @@ public class GlobalExceptionHandler {
|
||||
if (ex instanceof HttpRequestMethodNotSupportedException) {
|
||||
return httpRequestMethodNotSupportedExceptionHandler((HttpRequestMethodNotSupportedException) ex);
|
||||
}
|
||||
if (ex instanceof RequestNotPermitted) {
|
||||
return requestNotPermittedExceptionHandler(request, (RequestNotPermitted) ex);
|
||||
}
|
||||
if (ex instanceof ServiceException) {
|
||||
return serviceExceptionHandler((ServiceException) ex);
|
||||
}
|
||||
@ -163,6 +167,15 @@ public class GlobalExceptionHandler {
|
||||
return CommonResult.error(METHOD_NOT_ALLOWED.getCode(), String.format("请求方法不正确:%s", ex.getMessage()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Resilience4j 限流抛出的异常
|
||||
*/
|
||||
@ExceptionHandler(value = RequestNotPermitted.class)
|
||||
public CommonResult<?> requestNotPermittedExceptionHandler(HttpServletRequest req, RequestNotPermitted ex) {
|
||||
log.warn("[requestNotPermittedExceptionHandler][url({}) 访问过于频繁]", req.getRequestURL(), ex);
|
||||
return CommonResult.error(TOO_MANY_REQUESTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Spring Security 权限不足的异常
|
||||
*
|
||||
|
@ -1 +1 @@
|
||||
<http://www.iocoder.cn/Spring-Boot/SpringMVC/?dashboard>
|
||||
<http://www.iocoder.cn/Spring-Boot/SpringMVC/?yudao>
|
||||
|
@ -1,3 +1,7 @@
|
||||
### 请求 /get-permission-info 接口 => 成功
|
||||
### 请求 /tool/test-demo/get 接口 => 成功
|
||||
GET {{baseUrl}}/tool/test-demo/get?id=1
|
||||
Authorization: Bearer {{token}}
|
||||
|
||||
### 请求 /tool/test-demo/list 接口 => 成功
|
||||
GET {{baseUrl}}/tool/test-demo/list?ids=1
|
||||
Authorization: Bearer {{token}}
|
||||
|
@ -10,6 +10,7 @@ import cn.iocoder.dashboard.modules.tool.convert.test.ToolTestDemoConvert;
|
||||
import cn.iocoder.dashboard.modules.tool.dal.dataobject.test.ToolTestDemoDO;
|
||||
import cn.iocoder.dashboard.modules.tool.service.test.ToolTestDemoService;
|
||||
import com.baomidou.lock.annotation.Lock4j;
|
||||
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -78,6 +79,7 @@ public class ToolTestDemoController {
|
||||
@ApiOperation("获得测试示例列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('tool:test-demo:query')")
|
||||
@RateLimiter(name = "backendA")
|
||||
public CommonResult<List<ToolTestDemoRespVO>> getTestDemoList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<ToolTestDemoDO> list = testDemoService.getTestDemoList(ids);
|
||||
return success(ToolTestDemoConvert.INSTANCE.convertList(list));
|
||||
|
Reference in New Issue
Block a user