理解大量并行fetch请求/响应与超时延迟问题
理解大量并行fetch请求/响应与超时延迟问题
嘿,我来帮你拆解这个问题——你一次性发起10000个并行fetch请求,每个都设了2秒超时,但实际每个请求的运行时间却远超预期,对吧?这背后主要是几个关键因素在起作用:
HTTP连接池的默认限制:不管是Node.js还是浏览器,对同一个域名的并行HTTP连接数都有严格的默认限制(比如Node.js的https模块默认是5个,浏览器一般是6-8个)。你一口气扔出10000个请求,99%以上的请求都会被放进连接池的等待队列里,根本没法立刻发送到服务器。而你的代码里是从调用
run函数的瞬间就开始计时,所以这个runtime会把排队等待可用连接的时间也加进去,自然会远远超过你设置的2秒超时。系统资源的瓶颈限制:10000个并行请求意味着需要创建大量的网络套接字、占用大量内存和CPU资源。操作系统的套接字数量是有限的,当你短时间内创建这么多套接字,系统会出现资源调度的延迟,甚至部分请求会因为无法分配到套接字而一直排队,这进一步拉长了每个请求的总耗时。
超时逻辑的实际触发时机:你设置的2秒超时是从调用
run就开始计时,但很多请求在2秒后才刚拿到连接开始发送,这时候超时信号触发,请求被中止,但这时候已经过了排队的时间+2秒,所以日志里的runtime就会是两者之和,轻松突破5秒。
给你几个解决思路:
- 严格控制并发数:别一次性发起所有请求,改成分批处理,比如每次只并发20-50个请求,等一批请求完成后再发起下一批。这样既能避免连接池排队,也不会压垮系统资源。
- 调整连接池限制(Node.js环境):可以适当调高HTTP/HTTPS模块的最大套接字数,但别太夸张,比如:
注意:调高这个值要量力而行,太大会导致系统资源耗尽。const https = require('https'); https.globalAgent.maxSockets = 100; // 根据服务器和系统性能调整 - 优化计时逻辑(可选):如果你希望
runtime只统计请求实际发送到服务器后的耗时,可以把start的计时点移到fetch调用的前一刻,但这样你就看不到排队的时间了,得根据你的需求来调整。
备注:内容来源于stack exchange,提问作者Nischit Pradhan




