mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-25 20:02:47 +00:00
Some checks failed
Build FastGPT images in Personal warehouse / get-vars (push) Waiting to run
Build FastGPT images in Personal warehouse / build-fastgpt-images (map[arch:amd64 runs-on:ubuntu-24.04]) (push) Blocked by required conditions
Build FastGPT images in Personal warehouse / build-fastgpt-images (map[arch:arm64 runs-on:ubuntu-24.04-arm]) (push) Blocked by required conditions
Build FastGPT images in Personal warehouse / release-fastgpt-images (push) Blocked by required conditions
Document deploy / sync-images (push) Has been cancelled
Document deploy / generate-timestamp (push) Has been cancelled
Document deploy / build-images (map[domain:https://fastgpt.cn suffix:cn]) (push) Has been cancelled
Document deploy / build-images (map[domain:https://fastgpt.io suffix:io]) (push) Has been cancelled
Document deploy / update-images (map[deployment:fastgpt-docs domain:https://fastgpt.cn kube_config:KUBE_CONFIG_CN suffix:cn]) (push) Has been cancelled
Document deploy / update-images (map[deployment:fastgpt-docs domain:https://fastgpt.io kube_config:KUBE_CONFIG_IO suffix:io]) (push) Has been cancelled
* perf: faq
* index
* delete dataset
* delete dataset
* perf: delete dataset
* init
* fix: faq
* refresh
* empty tip
* perf: delete type
* fix: some bugs (#6071)
* fix: publish channel doc link
* fix: checkbox disable hover style
* fix: huggingface.svg missing; update doc
* chore: update doc
* fix: typo
* fix: export log dateend;feat: file selector render (#6072)
* fix: export log dateend
* feat: file selector render
* perf: s3 controller
* team qpm limit & plan tracks (#6066)
* team qpm limit & plan tracks
* api entry qpm
* perf: computed days
* Revert "api entry qpm"
This reverts commit 1210c07217.
* perf: code
* system qpm limit
* system qpm limit
---------
Co-authored-by: archer <545436317@qq.com>
* perf: track
* remove export chat test
* doc
* feat: global agent (#6057)
* feat: global agent
* fix: agent
* fix: order display
* CHORE
* feat: error page log
* fix: var update
---------
Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
Co-authored-by: Roy <whoeverimf5@gmail.com>
82 lines
2.1 KiB
TypeScript
82 lines
2.1 KiB
TypeScript
/* 基于 Team 的限流 */
|
|
import { getGlobalRedisConnection } from '../../common/redis';
|
|
import { jsonRes } from '../../common/response';
|
|
import type { NextApiResponse } from 'next';
|
|
import { teamQPM } from '../../support/wallet/sub/utils';
|
|
import z from 'zod';
|
|
import { addLog } from '../system/log';
|
|
|
|
export enum LimitTypeEnum {
|
|
chat = 'chat'
|
|
}
|
|
|
|
const FrequencyLimitOptionSchema = z.union([
|
|
z.object({
|
|
type: z.literal(LimitTypeEnum.chat),
|
|
teamId: z.string()
|
|
})
|
|
]);
|
|
type FrequencyLimitOption = z.infer<typeof FrequencyLimitOptionSchema>;
|
|
|
|
const getLimitData = async (data: FrequencyLimitOption) => {
|
|
if (data.type === LimitTypeEnum.chat) {
|
|
const qpm = await teamQPM.getTeamQPMLimit(data.teamId);
|
|
|
|
if (!qpm) return;
|
|
|
|
return {
|
|
limit: qpm,
|
|
seconds: 60
|
|
};
|
|
}
|
|
return;
|
|
};
|
|
|
|
/*
|
|
true: 未达到限制
|
|
false: 达到了限制
|
|
*/
|
|
export const teamFrequencyLimit = async ({
|
|
teamId,
|
|
type,
|
|
res
|
|
}: FrequencyLimitOption & { res: NextApiResponse }) => {
|
|
const data = await getLimitData({ type, teamId });
|
|
if (!data) return true;
|
|
|
|
const { limit, seconds } = data;
|
|
|
|
const redis = getGlobalRedisConnection();
|
|
const key = `frequency:${type}:${teamId}`;
|
|
|
|
const result = await redis
|
|
.multi()
|
|
.incr(key)
|
|
.expire(key, seconds, 'NX') // 只在key不存在时设置过期时间
|
|
.exec();
|
|
|
|
if (!result) {
|
|
return true;
|
|
}
|
|
|
|
const currentCount = result[0][1] as number;
|
|
|
|
if (currentCount > limit) {
|
|
const remainingTime = await redis.ttl(key);
|
|
addLog.info(
|
|
`[Completion Limit] Team ${teamId} reached the limit of ${limit} requests per ${seconds} seconds. Remaining time: ${remainingTime} seconds.`
|
|
);
|
|
jsonRes(res, {
|
|
code: 429,
|
|
error: `Rate limit exceeded. Maximum ${limit} requests per ${seconds} seconds for this team. Please try again in ${remainingTime} seconds.`
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// 在响应头中添加限流信息
|
|
res.setHeader('X-RateLimit-Limit', limit);
|
|
res.setHeader('X-RateLimit-Remaining', Math.max(0, limit - currentCount));
|
|
res.setHeader('X-RateLimit-Reset', Date.now() + seconds * 1000);
|
|
return true;
|
|
};
|