init
This commit is contained in:
23
blade-service-api/blade-ratelimit-api/pom.xml
Normal file
23
blade-service-api/blade-ratelimit-api/pom.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>blade-service-api</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>blade-ratelimit-api</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-ratelimit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.config;
|
||||
|
||||
import org.springblade.core.launch.props.BladeProperties;
|
||||
import org.springblade.core.launch.server.ServerInfo;
|
||||
import org.springblade.core.ratelimit.IRateLimitHandler;
|
||||
import org.springblade.core.ratelimit.IRateLimitLogHandler;
|
||||
import org.springblade.core.ratelimit.config.RateLimitAutoConfiguration;
|
||||
import org.springblade.system.feign.IRateLimitClient;
|
||||
import org.springblade.system.handler.RateLimitHandler;
|
||||
import org.springblade.system.handler.RateLimitLogHandler;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 限流微服务配置。
|
||||
* <p>
|
||||
* 覆盖 starter {@link RateLimitAutoConfiguration} 的本地默认实现:规则取数 ({@link RateLimitHandler}) 与触发日志落库
|
||||
* ({@link RateLimitLogHandler}) 均改由 Feign 远程对接 blade-system,与所在服务的数据源无关,供任意业务服务复用。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureBefore(RateLimitAutoConfiguration.class)
|
||||
public class RateLimitConfiguration {
|
||||
|
||||
@Bean
|
||||
public IRateLimitHandler rateLimitHandler(IRateLimitClient rateLimitClient) {
|
||||
return new RateLimitHandler(rateLimitClient);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IRateLimitLogHandler rateLimitLogHandler(IRateLimitClient rateLimitClient, BladeProperties bladeProperties, ServerInfo serverInfo) {
|
||||
return new RateLimitLogHandler(rateLimitClient, bladeProperties, serverInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.feign;
|
||||
|
||||
import org.springblade.core.launch.constant.AppConstant;
|
||||
import org.springblade.core.ratelimit.RateLimitRule;
|
||||
import org.springblade.system.pojo.dto.RateLimitLogDTO;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限流规则 Feign接口类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@FeignClient(
|
||||
value = AppConstant.APPLICATION_SYSTEM_NAME,
|
||||
fallback = IRateLimitClientFallback.class
|
||||
)
|
||||
public interface IRateLimitClient {
|
||||
|
||||
String API_PREFIX = "/feign/client/rate-limit";
|
||||
String LIST = API_PREFIX + "/list";
|
||||
String SAVE_LOG = API_PREFIX + "/save-log";
|
||||
|
||||
/**
|
||||
* 获取全部启用的限流规则
|
||||
*
|
||||
* @return 限流规则集合
|
||||
*/
|
||||
@GetMapping(LIST)
|
||||
List<RateLimitRule> listEnabledRules();
|
||||
|
||||
/**
|
||||
* 保存限流触发日志
|
||||
*
|
||||
* @param rateLimitLog 限流触发日志
|
||||
* @return 影响行数
|
||||
*/
|
||||
@PostMapping(SAVE_LOG)
|
||||
int saveLog(@RequestBody RateLimitLogDTO rateLimitLog);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.feign;
|
||||
|
||||
import org.springblade.core.ratelimit.RateLimitRule;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.system.pojo.dto.RateLimitLogDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* IRateLimitClientFallback
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Component
|
||||
public class IRateLimitClientFallback implements IRateLimitClient {
|
||||
|
||||
@Override
|
||||
public List<RateLimitRule> listEnabledRules() {
|
||||
// 降级返回空规则集, 即全部放行
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int saveLog(RateLimitLogDTO rateLimitLog) {
|
||||
// 降级不落库
|
||||
return BladeConstant.DB_STATUS_0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.core.ratelimit.IRateLimitHandler;
|
||||
import org.springblade.core.ratelimit.RateLimitRule;
|
||||
import org.springblade.system.feign.IRateLimitClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限流规则处理器微服务实现。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class RateLimitHandler implements IRateLimitHandler {
|
||||
|
||||
private final IRateLimitClient rateLimitClient;
|
||||
|
||||
@Override
|
||||
public List<RateLimitRule> listEnabledRules() {
|
||||
return rateLimitClient.listEnabledRules();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.handler;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.launch.props.BladeProperties;
|
||||
import org.springblade.core.launch.server.ServerInfo;
|
||||
import org.springblade.core.ratelimit.IRateLimitLogHandler;
|
||||
import org.springblade.core.ratelimit.RateLimitRule;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.support.IdGenerator;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.core.tool.utils.UrlUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springblade.system.feign.IRateLimitClient;
|
||||
import org.springblade.system.pojo.dto.RateLimitLogDTO;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 限流触发日志处理器微服务实现。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class RateLimitLogHandler implements IRateLimitLogHandler {
|
||||
|
||||
private final IRateLimitClient rateLimitClient;
|
||||
private final BladeProperties bladeProperties;
|
||||
private final ServerInfo serverInfo;
|
||||
|
||||
@Override
|
||||
public void saveLog(RateLimitRule rule, String limitKey, HttpServletRequest request) {
|
||||
// 主线程采集上下文, 仅远程落库交由异步执行
|
||||
RateLimitLogDTO rateLimitLog = buildLog(rule, limitKey, request);
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
rateLimitClient.saveLog(rateLimitLog);
|
||||
} catch (Exception logException) {
|
||||
log.error("限流日志保存失败: {}", logException.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建限流触发日志
|
||||
*
|
||||
* @param rule 触发的限流规则
|
||||
* @param limitKey 实际限流计数 key
|
||||
* @param request 当前请求对象
|
||||
* @return 限流触发日志传输对象
|
||||
*/
|
||||
private RateLimitLogDTO buildLog(RateLimitRule rule, String limitKey, HttpServletRequest request) {
|
||||
RateLimitLogDTO rateLimitLog = new RateLimitLogDTO();
|
||||
rateLimitLog.setId(IdGenerator.getId());
|
||||
rateLimitLog.setTenantId(Func.toStrWithEmpty(AuthUtil.getTenantId(), BladeConstant.ADMIN_TENANT_ID));
|
||||
rateLimitLog.setServiceId(bladeProperties.getName());
|
||||
rateLimitLog.setServerIp(serverInfo.getIpWithPort());
|
||||
rateLimitLog.setServerHost(serverInfo.getHostName());
|
||||
rateLimitLog.setEnv(bladeProperties.getEnv());
|
||||
rateLimitLog.setLimitId(rule.getId());
|
||||
rateLimitLog.setLimitName(rule.getLimitName());
|
||||
rateLimitLog.setLimitDimension(rule.getLimitDimension());
|
||||
rateLimitLog.setLimitCount(rule.getLimitCount());
|
||||
rateLimitLog.setLimitPeriod(rule.getLimitPeriod());
|
||||
rateLimitLog.setTimeUnit(rule.getTimeUnit());
|
||||
rateLimitLog.setLimitKey(limitKey);
|
||||
rateLimitLog.setRequestUri(UrlUtil.getPath(request.getRequestURI()));
|
||||
rateLimitLog.setMethod(request.getMethod());
|
||||
rateLimitLog.setRemoteIp(WebUtil.getIP(request));
|
||||
rateLimitLog.setUserAgent(Func.toStr(request.getHeader(WebUtil.USER_AGENT_HEADER)));
|
||||
rateLimitLog.setParams(WebUtil.getRequestContent(request));
|
||||
rateLimitLog.setCreateBy(Func.toStrWithEmpty(AuthUtil.getUserAccount(), StringPool.EMPTY));
|
||||
rateLimitLog.setCreateTime(new Date());
|
||||
return rateLimitLog;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.system.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 限流触发日志传输对象。
|
||||
* <p>
|
||||
* 由被限流服务在主请求线程采集触发上下文 (含调用方服务标识与登录态), 经 Feign 远程发往 blade-system 落库,
|
||||
* 故所有字段在调用端填充, 服务端不依赖其自身上下文。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "限流触发日志传输对象")
|
||||
public class RateLimitLogDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "租户ID")
|
||||
private String tenantId;
|
||||
|
||||
@Schema(description = "触发服务名")
|
||||
private String serviceId;
|
||||
|
||||
@Schema(description = "服务器IP")
|
||||
private String serverIp;
|
||||
|
||||
@Schema(description = "服务器主机名")
|
||||
private String serverHost;
|
||||
|
||||
@Schema(description = "环境标识")
|
||||
private String env;
|
||||
|
||||
@Schema(description = "触发的限流规则ID")
|
||||
private Long limitId;
|
||||
|
||||
@Schema(description = "限流规则名称")
|
||||
private String limitName;
|
||||
|
||||
@Schema(description = "限流维度")
|
||||
private String limitDimension;
|
||||
|
||||
@Schema(description = "限流阈值")
|
||||
private Integer limitCount;
|
||||
|
||||
@Schema(description = "限流时间窗口")
|
||||
private Integer limitPeriod;
|
||||
|
||||
@Schema(description = "时间单位")
|
||||
private String timeUnit;
|
||||
|
||||
@Schema(description = "实际限流计数 key")
|
||||
private String limitKey;
|
||||
|
||||
@Schema(description = "请求地址")
|
||||
private String requestUri;
|
||||
|
||||
@Schema(description = "请求方法")
|
||||
private String method;
|
||||
|
||||
@Schema(description = "请求IP")
|
||||
private String remoteIp;
|
||||
|
||||
@Schema(description = "用户代理")
|
||||
private String userAgent;
|
||||
|
||||
@Schema(description = "请求参数")
|
||||
private String params;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String createBy;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Created by Blade.
|
||||
*
|
||||
* @author zhuangqian
|
||||
*/
|
||||
package org.springblade.system.pojo.vo;
|
||||
Reference in New Issue
Block a user