前端控制并发几十个请求

在处理大量并发请求时,为了避免服务器过载或客户端性能下降,可以使用并发控制技术。以下是几种常见的方式:

1. 使用 Promise.allSettled 和分批处理

将请求分成小批次,并逐批执行,每一批的大小由并发限制决定:

async function fetchWithConcurrency(urls, maxConcurrency) {
    const results = [];
    while (urls.length > 0) {
        // 取出一批URL
        const batch = urls.splice(0, maxConcurrency);
        // 使用 Promise.allSettled 执行一批请求
        const batchResults = await Promise.allSettled(
            batch.map(url => fetch(url))
        );
        results.push(...batchResults);
    }
    return results;
}

const urls = Array(100).fill('https://example.com/api');
fetchWithConcurrency(urls, 5).then(results => {
    console.log(results); // 输出每个请求的状态与结果
});

2. 使用队列方式控制并发

创建一个队列控制器,通过限制同时运行的 Promise 数量来管理并发:

class PromiseQueue {
    constructor(maxConcurrency) {
        this.maxConcurrency = maxConcurrency;
        this.running = 0;
        this.queue = [];
    }

    enqueue(task) {
        return new Promise((resolve, reject) => {
            this.queue.push(() => task().then(resolve, reject));
            this.runNext();
        });
    }

    runNext() {
        if (this.running >= this.maxConcurrency || this.queue.length === 0) {
            return;
        }
        const task = this.queue.shift();
        this.running++;
        task().finally(() => {
            this.running--;
            this.runNext();
        });
    }
}

// 使用队列
const queue = new PromiseQueue(5); // 并发数为 5
const urls = Array(100).fill('https://example.com/api');

Promise.all(
    urls.map(url => queue.enqueue(() => fetch(url)))
).then(results => {
    console.log(results);
});

3. 使用第三方库

可以使用现成的库如 p-limit 或 promise-pool 来管理并发。

示例:使用 p-limit

const pLimit = require('p-limit');

const limit = pLimit(5); // 最大并发数 5

const urls = Array(100).fill('https://example.com/api');
const tasks = urls.map(url => limit(() => fetch(url)));

Promise.all(tasks).then(results => {
    console.log(results);
});

示例:使用 promise-pool

const { promisePool } = require('promise-pool');

const urls = Array(100).fill('https://example.com/api');

async function fetchUrl(url) {
    const response = await fetch(url);
    return response.json();
}

promisePool({ items: urls, concurrency: 5, task: fetchUrl })
    .then(results => {
        console.log(results);
    });

4. 浏览器专用:AbortController 限制超时

结合超时机制,使用 AbortController 提前中止请求,防止某些请求过长拖慢整个流程:

async function fetchWithTimeout(url, timeout = 5000) {
    const controller = new AbortController();
    const signal = controller.signal;
    const timeoutId = setTimeout(() => controller.abort(), timeout);

    try {
        const response = await fetch(url, { signal });
        return await response.json();
    } catch (err) {
        return { error: 'Timeout or network error' };
    } finally {
        clearTimeout(timeoutId);
    }
}

// 并发控制逻辑同上

选择建议:

任务数量多,但单任务时间较短: 分批或 PromiseQueue 更适合。
任务数量多且复杂: 使用 p-limit 等库实现并发控制。
实时性要求高: 考虑 AbortController 或合理设置超时策略。

### 处理每秒十几万高并发请求的最佳实践和架构设计 #### 1. 流量控制与限流策略 为了应对突发的大规模流量冲击,采用分层的流量控制系统至关重要。在HTTP请求到达Web服务器之前,通过前置的一层粗细管道机制来管理流量。入口端配置为能够承受更高的吞吐量(例如100万次/秒),而出口则严格限制到目标处理能力范围之内(如10万个请求/秒)。超出限额的部分被暂时存储于缓冲区中排队等候,直至有空闲资源可用时再逐步释放给后端服务进行实际处理[^3]。 #### 2. 负载均衡器的选择与优化 选用高效的负载均衡算法可以有效提升系统的整体响应速度和服务质量。常见的做法是在前端部署多个反向代理节点形成集群,并利用一致性哈希等高级调度技术确保各实例间的工作负荷均匀分布。此外,还需定期监控并调整这些组件的状态参数以适应动态变化的需求模式。 #### 3. 数据库读写分离及缓存机制的应用 针对数据库层面的压力缓解措施主要包括两点:一是实施主从复制模型下的读操作分流;二是引入分布式内存对象缓存系统(比如Redis或Memcached)用于频繁访问的数据项预取与暂存。前者有助于减轻单一数据源所承担的任务负担,后者则能在很大程度上降低磁盘I/O频率从而加快检索效率[^1]。 ```sql -- MySQL 主从同步配置示例 CHANGE MASTER TO MASTER_HOST='master_host_ip', MASTER_USER='replication_user', MASTER_PASSWORD='password'; START SLAVE; ``` #### 4. 并发编程技巧与异步任务队列的支持 对于应用程序内部而言,则要充分利用多线程或多进程特性以及事件驱动型框架的优势来进行高效的任务分配与执行。特别是当涉及到长时间运行的操作(像文件上传下载、邮件发送接收等)时,应当将其转化为后台作业并通过消息中间件(RabbitMQ, Kafka 等)传递至专门负责此类工作的消费者进程中去独立完成[^2]。 ```python import asyncio async def handle_request(request): await some_async_operation() loop = asyncio.get_event_loop() tasks = [handle_request(req) for req in requests] results = loop.run_until_complete(asyncio.gather(*tasks)) ``` #### 5. 容错性和弹性伸缩的设计考量 最后也是不容忽视的一个方面就是构建具有高度容错能力和自动扩展特性的微服务体系结构。借助容器编排平台(Kubernetes)、云服务商提供的Serverless解决方案或者其他类似的工具集可以帮助运维团队轻松实现按需调配计算资源的目标,进而保障业务连续性不受影响的同时也提高了成本效益比率[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值