feat: QPS Limit middleware (#2956)

* feat: QPS Limit middleware

* chore: use request-ip to get client ip

* feat: frequencyLimit schema
This commit is contained in:
Finley Ge
2024-10-25 10:08:59 +08:00
committed by GitHub
parent bb727b0710
commit 75494f8d01
8 changed files with 144 additions and 28 deletions

View File

@@ -0,0 +1,27 @@
import { getMongoModel, Schema } from '../../mongo';
import type { FrequencyLimitSchemaType } from './type';
const FrequencyLimitSchema = new Schema({
eventId: {
type: String,
required: true
},
amount: {
type: Number,
default: 0
},
expiredTime: {
type: Date,
required: true
}
});
try {
FrequencyLimitSchema.index({ eventId: 1 }, { unique: true });
FrequencyLimitSchema.index({ expiredTime: 1 }, { expireAfterSeconds: 0 });
} catch (error) {}
export const MongoFrequencyLimit = getMongoModel<FrequencyLimitSchemaType>(
'frequency_limit',
FrequencyLimitSchema
);

View File

@@ -0,0 +1,6 @@
export type FrequencyLimitSchemaType = {
_id: string;
eventId: string; // 事件ID
amount: number; // 当前数量
expiredTime: Date; // 什么时候过期,过期则重置
};

View File

@@ -0,0 +1,32 @@
import { AuthFrequencyLimitProps } from '@fastgpt/global/common/frequenctLimit/type';
import { MongoFrequencyLimit } from './schema';
import { readFromSecondary } from '../../mongo/utils';
export const authFrequencyLimit = async ({
eventId,
maxAmount,
expiredTime
}: AuthFrequencyLimitProps) => {
try {
// 对应 eventId 的 account+1, 不存在的话,则创建一个
const result = await MongoFrequencyLimit.findOneAndUpdate(
{
eventId
},
{
$inc: { amount: 1 },
$setOnInsert: { expiredTime }
},
{
upsert: true,
new: true,
...readFromSecondary
}
);
// 因为始终会返回+1的结果所以这里不能直接等需要多一个。
if (result.amount > maxAmount) {
return Promise.reject(result);
}
} catch (error) {}
};