简介
在现代Web应用中,处理并发请求是一个常见的需求。为了防止服务器过载或提高系统性能,我们通常需要限制并发请求的数量。本文介绍了一个简单的并发请求限制器的设计与实现,支持两种模式:队列模式(Queue Mode)和竞争模式(Race Mode)。通过这个限制器,您可以轻松控制并发请求的数量,确保系统在高负载下依然稳定运行。
代码实现
RequestLimit 类
export class RequestLimit {
constructor(maxConcurrentRequests, mode = "queue") {
this.maxConcurrentRequests = maxConcurrentRequests; // 最大并发请求数
this.requestQueue = []; // 请求队列
this.activeRequests = 0; // 当前活跃请求数
this.mode = mode; // 模式(队列或竞争)
}
// 创建 Queue 模式的实例
static createWithQueueMode(maxConcurrentRequests) {
return new RequestLimit(maxConcurrentRequests, "queue");
}
// 创建 Race 模式的实例
static createWithRaceMode(maxConcurrentRequests) {
return new RequestLimit(maxConcurrentRequests, "race");
}
async requestWrapper(request, response) {
return new Promise(resolve => {
const requestFunc = async () => {
this.activeRequests++;
try {
const result = await request();
response(result);
resolve(result);
} finally {
this.activeRequests--;
this.runNext(); // 尝试运行下一个请求
}
};
// 将请求添加到队列
this.requestQueue.push(requestFunc);
this.runRace(); // 尝试运行请求
});
}
// 运行下一个请求
runNext() {
while (this.activeRequests < this.maxConcurrentRequests && this.requestQueue.length > 0) {
const nextRequest = this.requestQueue.shift(); // 从队列中取出下一个请求
nextRequest(); // 执行下一个请求
}
}
// Race模式:控制并发请求数
runRace() {
while (this.activeRequests < this.maxConcurrentRequests && this.requestQueue.length > 0) {
const nextRequest = this.requestQueue.shift(); // 从队列中取出下一个请求
nextRequest(); // 执行下一个请求
}
}
}
测试代码
// 随机生成 1 到 5 秒的请求持续时间
const getRandomDuration = () => Math.floor(Math.random() * 5000) + 1000;
// 模拟异步请求函数,带有随机持续时间和时间戳
const createRequest = (id) => () => new Promise(resolve => {
const duration = getRandomDuration();
const startTime = new Date().toLocaleTimeString();
console.log(`Request ${id} started at ${startTime} (duration: ${duration} ms)`);
setTimeout(() => {
const endTime = new Date().toLocaleTimeString();
console.log(`Request ${id} finished at ${endTime}`);
resolve(`Result of request ${id}`);
}, duration);
});
// 测试函数
const testRequestLimit = async (mode, maxConcurrentRequests, totalRequests) => {
console.log(`\nTesting ${mode} mode with max ${maxConcurrentRequests} concurrent requests:`);
const limiter = mode === 'queue'
? RequestLimit.createWithQueueMode(maxConcurrentRequests)
: RequestLimit.createWithRaceMode(maxConcurrentRequests);
const responses = [];
const responseCollector = response => {
console.log("-------------->", response);
};
// 创建并发请求
for (let i = 1; i <= totalRequests; i++) {
limiter.requestWrapper(createRequest(i), responseCollector);
}
};
// 测试参数
const maxConcurrentRequests = 3; // 最大并发请求数
const totalRequests = 10; // 总请求数
// 运行测试
(async () => {
await testRequestLimit('race', maxConcurrentRequests, totalRequests);
})();
关键点
-
RequestLimit 类:
constructor
: 初始化最大并发请求数、请求队列、当前活跃请求数和模式。createWithQueueMode
和createWithRaceMode
: 静态方法,用于创建不同模式的实例。requestWrapper
: 包装请求,将请求添加到队列并尝试运行请求。runNext
: 运行下一个请求,确保并发数不超过限制。runRace
: 在 race 模式下控制并发请求数。
-
测试代码:
getRandomDuration
: 生成 1 到 5 秒的随机请求持续时间。createRequest
: 模拟异步请求,带有随机持续时间和时间戳。testRequestLimit
: 测试函数,创建并发请求并收集结果。- 运行测试时,选择 race 模式并设置最大并发请求数和总请求数。
总结
通过这个简单的并发请求限制器,您可以轻松控制并发请求的数量,确保系统在高负载下依然稳定运行。无论是队列模式还是竞争模式,都能满足不同的需求。希望这个实现对您有所帮助!