1
0
mirror of https://github.com/ZeroCatDev/ClassworksKV.git synced 2025-07-01 20:09:23 +00:00
ClassworksKV/scripts/test-rate-limit.js

250 lines
6.8 KiB
JavaScript

import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
// 配置
const BASE_URL = 'http://localhost:3030'; // 修改为你的服务器地址和端口
const TEST_NAMESPACE = uuidv4(); // 生成随机命名空间用于测试
const DELAY_BETWEEN_REQUESTS = 100; // 请求间隔时间(毫秒)
// 测试结果统计
const stats = {
success: 0,
rateLimited: 0,
errors: 0,
totalRequests: 0
};
// 颜色输出
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m'
};
/**
* 延迟函数
* @param {number} ms 延迟毫秒数
*/
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
/**
* 发送请求并处理响应
* @param {string} method HTTP方法
* @param {string} endpoint 请求路径
* @param {object} data 请求数据
* @param {number} index 请求索引
*/
async function sendRequest(method, endpoint, data = null, index) {
stats.totalRequests++;
const url = `${BASE_URL}${endpoint}`;
try {
const startTime = Date.now();
const response = await axios({
method,
url,
data,
validateStatus: () => true // 不抛出HTTP错误
});
const duration = Date.now() - startTime;
// 处理响应
if (response.status === 429) { // 请求被限速
stats.rateLimited++;
console.log(`${colors.yellow}[${index}] ${method} ${endpoint} - 被限速 (${duration}ms)${colors.reset}`);
return { limited: true, status: response.status };
} else if (response.status >= 200 && response.status < 300) { // 成功
stats.success++;
console.log(`${colors.green}[${index}] ${method} ${endpoint} - 成功: ${response.status} (${duration}ms)${colors.reset}`);
return { limited: false, status: response.status, data: response.data };
} else { // 其他错误
stats.errors++;
console.log(`${colors.red}[${index}] ${method} ${endpoint} - 错误: ${response.status} (${duration}ms)${colors.reset}`);
return { limited: false, status: response.status, error: response.data };
}
} catch (error) {
stats.errors++;
console.log(`${colors.red}[${index}] ${method} ${endpoint} - 异常: ${error.message}${colors.reset}`);
return { limited: false, error: error.message };
}
}
/**
* 测试全局限速
*/
async function testGlobalRateLimit() {
console.log(`\n${colors.cyan}===== 测试全局限速 (200/15分钟) =====${colors.reset}`);
const requests = [];
// 发送250个请求 (应该有50个被限速)
for (let i = 0; i < 250; i++) {
requests.push(sendRequest('GET', '/check', null, i));
await delay(DELAY_BETWEEN_REQUESTS);
}
await Promise.all(requests);
printStats('全局限速测试');
}
/**
* 测试API限速
*/
async function testApiRateLimit() {
console.log(`\n${colors.cyan}===== 测试API限速 (50/5分钟) =====${colors.reset}`);
resetStats();
const requests = [];
// 发送60个请求 (应该有10个被限速)
for (let i = 0; i < 60; i++) {
requests.push(sendRequest('GET', '/check', null, i));
await delay(DELAY_BETWEEN_REQUESTS);
}
await Promise.all(requests);
printStats('API限速测试');
}
/**
* 测试写操作限速
*/
async function testWriteRateLimit() {
console.log(`\n${colors.cyan}===== 测试写操作限速 (10/分钟) =====${colors.reset}`);
resetStats();
const requests = [];
// 发送15个写请求 (应该有5个被限速)
for (let i = 0; i < 15; i++) {
const key = `test-key-${i}`;
const data = { value: `test-value-${i}`, timestamp: Date.now() };
requests.push(sendRequest('POST', `/${TEST_NAMESPACE}/${key}`, data, i));
await delay(DELAY_BETWEEN_REQUESTS);
}
await Promise.all(requests);
printStats('写操作限速测试');
}
/**
* 测试删除操作限速
*/
async function testDeleteRateLimit() {
console.log(`\n${colors.cyan}===== 测试删除操作限速 (5/5分钟) =====${colors.reset}`);
resetStats();
// 先创建几个键值对
for (let i = 0; i < 10; i++) {
const key = `delete-key-${i}`;
const data = { value: `delete-value-${i}` };
await sendRequest('POST', `/${TEST_NAMESPACE}/${key}`, data, `创建-${i}`);
await delay(DELAY_BETWEEN_REQUESTS);
}
resetStats();
const requests = [];
// 发送8个删除请求 (应该有3个被限速)
for (let i = 0; i < 8; i++) {
const key = `delete-key-${i}`;
requests.push(sendRequest('DELETE', `/${TEST_NAMESPACE}/${key}`, null, i));
await delay(DELAY_BETWEEN_REQUESTS);
}
await Promise.all(requests);
printStats('删除操作限速测试');
}
/**
* 测试认证限速
*/
async function testAuthRateLimit() {
console.log(`\n${colors.cyan}===== 测试认证限速 (5/30分钟) =====${colors.reset}`);
resetStats();
const requests = [];
// 发送8个认证请求 (应该有3个被限速)
for (let i = 0; i < 8; i++) {
requests.push(sendRequest('POST', '/auth', { username: 'test', password: 'wrong' }, i));
await delay(DELAY_BETWEEN_REQUESTS);
}
await Promise.all(requests);
printStats('认证限速测试');
}
/**
* 重置统计数据
*/
function resetStats() {
stats.success = 0;
stats.rateLimited = 0;
stats.errors = 0;
stats.totalRequests = 0;
}
/**
* 打印统计信息
*/
function printStats(testName) {
console.log(`\n${colors.magenta}${testName}结果:${colors.reset}`);
console.log(`总请求数: ${stats.totalRequests}`);
console.log(`成功请求: ${stats.success}`);
console.log(`被限速请求: ${stats.rateLimited}`);
console.log(`错误请求: ${stats.errors}`);
console.log(`限速比例: ${Math.round((stats.rateLimited / stats.totalRequests) * 100)}%`);
}
/**
* 主函数
*/
async function main() {
console.log(`${colors.cyan}开始测试限速功能...${colors.reset}`);
console.log(`使用测试命名空间: ${TEST_NAMESPACE}`);
try {
// 测试全局限速
await testGlobalRateLimit();
// 重置统计并等待一段时间
resetStats();
await delay(2000);
// 测试API限速
await testApiRateLimit();
// 重置统计并等待一段时间
resetStats();
await delay(2000);
// 测试写操作限速
await testWriteRateLimit();
// 重置统计并等待一段时间
resetStats();
await delay(2000);
// 测试删除操作限速
await testDeleteRateLimit();
// 重置统计并等待一段时间
resetStats();
await delay(2000);
// 测试认证限速
await testAuthRateLimit();
// 清理测试数据
console.log(`\n${colors.cyan}清理测试数据...${colors.reset}`);
await sendRequest('DELETE', `/${TEST_NAMESPACE}`, null, 'cleanup');
console.log(`\n${colors.green}所有测试完成!${colors.reset}`);
} catch (error) {
console.error(`${colors.red}测试过程中发生错误: ${error.message}${colors.reset}`);
}
}
// 执行主函数
main().catch(console.error);