mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-09-11 06:28:50 +00:00
【issues/9871】AI聊天助手访问限流配置统一到ai-chat,空或非正数时关闭对应限流
This commit is contained in:
parent
45f7be38d5
commit
169872c4b4
@ -49,6 +49,29 @@ public class AiChatConfig {
|
||||
*/
|
||||
private ModelConfig aiModelEmbed = new ModelConfig();
|
||||
|
||||
/**
|
||||
* AI 聊天助手访问限流配置
|
||||
*/
|
||||
private RateLimitConfig rateLimit = new RateLimitConfig();
|
||||
|
||||
/**
|
||||
* AI 聊天助手访问限流参数
|
||||
*
|
||||
* @author scott
|
||||
* @since 2026-09-01 issues/9871 AI聊天助手访问限流配置优化
|
||||
*/
|
||||
@Data
|
||||
public static class RateLimitConfig {
|
||||
/** 每会话每分钟最多发送消息次数,为空或小于等于 0 时不限制 */
|
||||
private Integer sendPerSessionPerMinute;
|
||||
|
||||
/** 每 IP 每分钟最多发送消息次数,为空或小于等于 0 时不限制 */
|
||||
private Integer sendPerIpPerMinute;
|
||||
|
||||
/** 每会话每小时最多上传文件次数,为空或小于等于 0 时不限制 */
|
||||
private Integer uploadPerSessionPerHour;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ModelConfig {
|
||||
/**
|
||||
@ -102,4 +125,4 @@ public class AiChatConfig {
|
||||
private double volume = 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,8 +3,7 @@ package org.jeecg.modules.airag.app.service.impl;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.IpUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.jeecg.config.AiChatConfig;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -22,30 +21,25 @@ import java.util.concurrent.TimeUnit;
|
||||
@Service
|
||||
public class AiragChatRateLimitService {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 每会话每分钟最多发送消息次数
|
||||
*/
|
||||
@Value("${jeecg.airag.rate-limit.send-per-session-per-minute:20}")
|
||||
private int sendPerSessionPerMinute;
|
||||
|
||||
/**
|
||||
* 每 IP 每分钟最多发送消息次数
|
||||
*/
|
||||
@Value("${jeecg.airag.rate-limit.send-per-ip-per-minute:60}")
|
||||
private int sendPerIpPerMinute;
|
||||
|
||||
/**
|
||||
* 每会话每小时最多上传文件次数
|
||||
*/
|
||||
@Value("${jeecg.airag.rate-limit.upload-per-session-per-hour:20}")
|
||||
private int uploadPerSessionPerHour;
|
||||
private final RedisTemplate redisTemplate;
|
||||
private final AiChatConfig.RateLimitConfig rateLimit;
|
||||
|
||||
private static final DateTimeFormatter MINUTE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
|
||||
private static final DateTimeFormatter HOUR_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHH");
|
||||
|
||||
/**
|
||||
* 构造 AI 聊天助手访问限流服务
|
||||
*
|
||||
* @param redisTemplate Redis 操作模板
|
||||
* @param aiChatConfig AI 聊天配置
|
||||
* @author scott
|
||||
* @since 2026-09-01 issues/9871 AI聊天助手访问限流配置优化
|
||||
*/
|
||||
public AiragChatRateLimitService(RedisTemplate redisTemplate, AiChatConfig aiChatConfig) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.rateLimit = aiChatConfig.getRateLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 /airag/chat/send 调用频次
|
||||
*
|
||||
@ -56,9 +50,9 @@ public class AiragChatRateLimitService {
|
||||
String clientIp = IpUtils.getIpAddr(request);
|
||||
String minute = LocalDateTime.now().format(MINUTE_FORMAT);
|
||||
|
||||
checkLimit("airag:rate:send:session:" + sessionId + ":" + minute, sendPerSessionPerMinute, 120,
|
||||
checkLimit("airag:rate:send:session:" + sessionId + ":" + minute, rateLimit.getSendPerSessionPerMinute(), 120,
|
||||
"发送消息过于频繁,请稍后再试");
|
||||
checkLimit("airag:rate:send:ip:" + clientIp + ":" + minute, sendPerIpPerMinute, 120,
|
||||
checkLimit("airag:rate:send:ip:" + clientIp + ":" + minute, rateLimit.getSendPerIpPerMinute(), 120,
|
||||
"发送消息过于频繁,请稍后再试");
|
||||
}
|
||||
|
||||
@ -72,9 +66,9 @@ public class AiragChatRateLimitService {
|
||||
String clientIp = IpUtils.getIpAddr(request);
|
||||
String hour = LocalDateTime.now().format(HOUR_FORMAT);
|
||||
|
||||
checkLimit("airag:rate:upload:session:" + sessionId + ":" + hour, uploadPerSessionPerHour, 7200,
|
||||
checkLimit("airag:rate:upload:session:" + sessionId + ":" + hour, rateLimit.getUploadPerSessionPerHour(), 7200,
|
||||
"上传文件过于频繁,请稍后再试");
|
||||
checkLimit("airag:rate:upload:ip:" + clientIp + ":" + hour, uploadPerSessionPerHour, 7200,
|
||||
checkLimit("airag:rate:upload:ip:" + clientIp + ":" + hour, rateLimit.getUploadPerSessionPerHour(), 7200,
|
||||
"上传文件过于频繁,请稍后再试");
|
||||
}
|
||||
|
||||
@ -85,7 +79,10 @@ public class AiragChatRateLimitService {
|
||||
* @param limit 窗口上限
|
||||
* @param expireSeconds key 过期时间(秒)
|
||||
*/
|
||||
private void checkLimit(String key, int limit, int expireSeconds, String errorMessage) {
|
||||
private void checkLimit(String key, Integer limit, int expireSeconds, String errorMessage) {
|
||||
if (limit == null || limit <= 0) {
|
||||
return;
|
||||
}
|
||||
Long count = redisTemplate.opsForValue().increment(key, 1);
|
||||
if (count == null) {
|
||||
return;
|
||||
|
||||
@ -190,6 +190,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -254,15 +262,6 @@ jeecg:
|
||||
# Unipush配置 云函数调用 URL 化地址
|
||||
unicloud:
|
||||
pushUrl:
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -166,6 +166,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -225,15 +233,6 @@ jeecg:
|
||||
endpoint: https://api.search.brave.com/res/v1/web/search
|
||||
count: 10
|
||||
timeout: 15
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -188,6 +188,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -377,4 +385,4 @@ justauth:
|
||||
cache:
|
||||
type: default
|
||||
prefix: 'demo::'
|
||||
timeout: 1h
|
||||
timeout: 1h
|
||||
|
||||
@ -183,6 +183,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -245,15 +253,6 @@ jeecg:
|
||||
# Unipush配置 云函数调用 URL 化地址
|
||||
unicloud:
|
||||
pushUrl:
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -180,6 +180,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -239,15 +247,6 @@ jeecg:
|
||||
endpoint: https://api.search.brave.com/res/v1/web/search
|
||||
count: 10
|
||||
timeout: 15
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -193,6 +193,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -252,15 +260,6 @@ jeecg:
|
||||
endpoint: https://api.search.brave.com/res/v1/web/search
|
||||
count: 10
|
||||
timeout: 15
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -186,6 +186,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
|
||||
@ -175,6 +175,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
@ -234,15 +242,6 @@ jeecg:
|
||||
endpoint: https://api.search.brave.com/res/v1/web/search
|
||||
count: 10
|
||||
timeout: 15
|
||||
airag:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# 平台上线安全配置
|
||||
firewall:
|
||||
# 数据源安全 (开启后,Online报表和图表的数据源为必填)
|
||||
|
||||
@ -190,6 +190,14 @@ jeecg:
|
||||
timeout: 60
|
||||
skills-dir:
|
||||
skills-shell-dir:
|
||||
# AI聊天助手访问限流配置
|
||||
rate-limit:
|
||||
# 单 session 每分钟上限
|
||||
send-per-session-per-minute: 10
|
||||
# 单 IP 每分钟上限
|
||||
send-per-ip-per-minute: 20
|
||||
# 单 session 每小时上限
|
||||
upload-per-session-per-hour: 20
|
||||
# AI文生图绘画
|
||||
ai-model-draw:
|
||||
# 提供商 OPENAI/ZHIPU/QWEN
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user